mirror of
https://github.com/penpot/penpot.git
synced 2025-04-15 16:31:25 -05:00
More work on element options.
This commit is contained in:
parent
43b6056c1e
commit
e1a15aed9a
5 changed files with 150 additions and 45 deletions
src/uxbox
|
@ -15,30 +15,40 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(def ^:static +shape-schema+
|
||||
{:x [v/integer]
|
||||
:y [v/integer]
|
||||
:width [v/integer]
|
||||
:height [v/integer]
|
||||
:type [v/required sc/shape-type]})
|
||||
{:x [sc/integer]
|
||||
:y [sc/integer]
|
||||
:width [sc/integer]
|
||||
:height [sc/integer]
|
||||
:type [sc/required sc/shape-type]})
|
||||
|
||||
(def ^:static +shape-update-size-schema+
|
||||
{:width [v/integer]
|
||||
:height [v/integer]
|
||||
:lock [v/boolean]})
|
||||
(def ^:static +shape-size-schema+
|
||||
{:width [sc/integer]
|
||||
:height [sc/integer]
|
||||
:lock [sc/boolean]})
|
||||
|
||||
(def ^:static +shape-update-fill-schema+
|
||||
(def ^:static +shape-fill-attrs-schema+
|
||||
{:color [sc/color]
|
||||
:opacity [v/number]})
|
||||
:opacity [sc/number]})
|
||||
|
||||
(def ^:static +shape-update-stroke-schema+
|
||||
(def ^:static +shape-stroke-attrs-schema+
|
||||
{:color [sc/color]
|
||||
:opacity [v/number]})
|
||||
:width [sc/integer]
|
||||
:type [sc/keyword]
|
||||
:opacity [sc/number]})
|
||||
|
||||
(def ^:static +shape-update-position-schema+
|
||||
{:x1 [v/integer]
|
||||
:y1 [v/integer]
|
||||
:x2 [v/integer]
|
||||
:y2 [v/integer]})
|
||||
(def ^:static +shape-line-attrs-schema+
|
||||
{:x1 [sc/integer]
|
||||
:y1 [sc/integer]
|
||||
:x2 [sc/integer]
|
||||
:y2 [sc/integer]})
|
||||
|
||||
(def ^:static +shape-radius-attrs-schema+
|
||||
{:rx [sc/integer]
|
||||
:ry [sc/integer]})
|
||||
|
||||
(def ^:static +shape-position-schema+
|
||||
{:x [sc/integer]
|
||||
:y [sc/integer]})
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Events (explicit)
|
||||
|
@ -194,13 +204,14 @@
|
|||
(let [shape (get-in state [:shapes-by-id sid])]
|
||||
(update-in state [:shapes-by-id sid] sh/-move delta)))))
|
||||
|
||||
(defn update-line
|
||||
[sid props]
|
||||
(defn update-line-attrs
|
||||
[sid {:keys [x1 y1 x2 y2] :as opts}]
|
||||
(sc/validate! +shape-line-attrs-schema+ opts)
|
||||
(reify
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(let [shape (get-in state [:shapes-by-id sid])
|
||||
props (select-keys props [:x1 :y1 :x2 :y2])
|
||||
props (select-keys opts [:x1 :y1 :x2 :y2])
|
||||
props' (select-keys shape [:x1 :y1 :x2 :y2])]
|
||||
(update-in state [:shapes-by-id sid] sh/-initialize
|
||||
(merge props' props))))))
|
||||
|
@ -224,7 +235,7 @@
|
|||
WARN: only works with shapes that works
|
||||
with height and width such are"
|
||||
[sid {:keys [width height] :as opts}]
|
||||
(sc/validate! +shape-update-size-schema+ opts)
|
||||
(sc/validate! +shape-size-schema+ opts)
|
||||
(reify
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
|
@ -234,17 +245,15 @@
|
|||
(defn update-position
|
||||
"Update the start position coordenate of the shape."
|
||||
[sid {:keys [x y] :as opts}]
|
||||
(sc/validate! +shape-update-position-schema+ opts)
|
||||
(sc/validate! +shape-position-schema+ opts)
|
||||
(reify
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(update-in state [:shapes-by-id sid] sh/-move' [x y]))))
|
||||
|
||||
;; TODO: rename fill to "color" for consistency.
|
||||
|
||||
(defn update-fill-attrs
|
||||
[sid {:keys [color opacity] :as opts}]
|
||||
(sc/validate! +shape-update-fill-schema+ opts)
|
||||
(sc/validate! +shape-fill-attrs-schema+ opts)
|
||||
(reify
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
|
@ -254,8 +263,8 @@
|
|||
(when opacity {:opacity opacity})))))
|
||||
|
||||
(defn update-stroke-attrs
|
||||
[sid {:keys [color opacity width type] :as opts}]
|
||||
(sc/validate! +shape-update-stroke-schema+ opts)
|
||||
[sid {:keys [color opacity type width] :as opts}]
|
||||
(sc/validate! +shape-stroke-attrs-schema+ opts)
|
||||
(reify
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
|
@ -266,6 +275,17 @@
|
|||
(when color {:stroke color})
|
||||
(when opacity {:stroke-opacity opacity})))))
|
||||
|
||||
(defn update-radius-attrs
|
||||
[sid {:keys [rx ry] :as opts}]
|
||||
(sc/validate! +shape-radius-attrs-schema+ opts)
|
||||
(reify
|
||||
rs/UpdateEvent
|
||||
(-apply-update [_ state]
|
||||
(update-in state [:shapes-by-id sid]
|
||||
merge
|
||||
(when rx {:rx rx})
|
||||
(when ry {:ry ry})))))
|
||||
|
||||
(defn hide-shape
|
||||
[sid]
|
||||
(reify
|
||||
|
@ -455,7 +475,7 @@
|
|||
"Update the fill related attributed on
|
||||
selected shapes."
|
||||
[opts]
|
||||
(sc/validate! +shape-update-fill-schema+ opts)
|
||||
(sc/validate! +shape-fill-attrs-schema+ opts)
|
||||
(reify
|
||||
rs/WatchEvent
|
||||
(-apply-watch [_ state]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
(ns uxbox.schema
|
||||
(:refer-clojure :exclude [keyword uuid vector])
|
||||
(:refer-clojure :exclude [keyword uuid vector boolean])
|
||||
(:require [bouncer.core :as b]
|
||||
[bouncer.validators :as v]
|
||||
[cuerdas.core :as str]
|
||||
|
@ -49,6 +49,8 @@
|
|||
|
||||
(def required v/required)
|
||||
(def number v/number)
|
||||
(def integer v/integer)
|
||||
(def boolean v/boolean)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Public Api
|
||||
|
|
|
@ -196,11 +196,8 @@
|
|||
|
||||
(defmethod -move' :builtin/circle
|
||||
[shape [x y]]
|
||||
(let [{:keys [cx cy rx ry]} shape
|
||||
x1 (- cx rx)
|
||||
y1 (- cy ry)
|
||||
dx (if x (- (:x1 shape) x) 0)
|
||||
dy (if y (- (:y1 shape) y) 0)]
|
||||
(let [dx (if x (- (:cx shape) x) 0)
|
||||
dy (if y (- (:cy shape) y) 0)]
|
||||
(-move shape [dx dy])))
|
||||
|
||||
(defmethod -move' :default
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(def ^:static ^:private +style-attrs+
|
||||
#{:fill :opacity :stroke :stroke-opacity :stroke-width :stroke-type})
|
||||
#{:fill :opacity :stroke :stroke-opacity :stroke-width :stroke-type :rx :ry})
|
||||
|
||||
(defn- transform-stroke-type
|
||||
[attrs]
|
||||
|
|
|
@ -18,14 +18,18 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(def ^:static ^:private +menus-map+
|
||||
{:builtin/icon [:menu/rect-measures :menu/fill :menu/stroke]
|
||||
{:builtin/icon [:menu/icon-measures :menu/fill :menu/stroke]
|
||||
:builtin/rect [:menu/rect-measures :menu/fill :menu/stroke]
|
||||
:builtin/line [:menu/line-measures :menu/stroke]
|
||||
:builtin/circle [:menu/circle-measures :menu/fill :menu/stroke]
|
||||
:builtin/group []})
|
||||
|
||||
(def ^:static ^:private +menus-by-id+
|
||||
{:menu/rect-measures
|
||||
{:menu/icon-measures
|
||||
{:name "Size, position & rotation"
|
||||
:icon i/infocard}
|
||||
|
||||
:menu/rect-measures
|
||||
{:name "Size, position & rotation"
|
||||
:icon i/infocard}
|
||||
|
||||
|
@ -192,7 +196,12 @@
|
|||
sid (:id shape)
|
||||
props {attr value}]
|
||||
(rs/emit! (dw/update-position sid props))))
|
||||
(on-border-change [attr event])]
|
||||
(on-border-change [attr event]
|
||||
(let [value (dom/event->value event)
|
||||
value (parse-int value nil)
|
||||
sid (:id shape)
|
||||
props {attr value}]
|
||||
(rs/emit! (dw/update-radius-attrs sid props))))]
|
||||
(html
|
||||
[:div.element-set {:key (str (:id menu))}
|
||||
[:div.element-set-title (:name menu)]
|
||||
|
@ -263,6 +272,83 @@
|
|||
]]]
|
||||
)))
|
||||
|
||||
|
||||
(defmethod -render-menu :menu/icon-measures
|
||||
[menu own shape]
|
||||
(letfn [(on-size-change [attr event]
|
||||
(let [value (dom/event->value event)
|
||||
value (parse-int value 0)
|
||||
sid (:id shape)
|
||||
props {attr value}]
|
||||
(rs/emit! (dw/update-size sid props))))
|
||||
(on-rotation-change [event]
|
||||
(let [value (dom/event->value event)
|
||||
value (parse-int value 0)
|
||||
sid (:id shape)]
|
||||
(rs/emit! (dw/update-rotation sid value))))
|
||||
(on-pos-change [attr event]
|
||||
(let [value (dom/event->value event)
|
||||
value (parse-int value nil)
|
||||
sid (:id shape)
|
||||
props {attr value}]
|
||||
(rs/emit! (dw/update-position sid props))))]
|
||||
(html
|
||||
[:div.element-set {:key (str (:id menu))}
|
||||
[:div.element-set-title (:name menu)]
|
||||
[:div.element-set-content
|
||||
;; SLIDEBAR FOR ROTATION AND OPACITY
|
||||
[:span "Size"]
|
||||
[:div.row-flex
|
||||
[:input#width.input-text
|
||||
{:placeholder "Width"
|
||||
:type "number"
|
||||
:min "0"
|
||||
:value (:width shape)
|
||||
:on-change (partial on-size-change :width)}]
|
||||
[:div.lock-size i/lock]
|
||||
[:input#width.input-text
|
||||
{:placeholder "Height"
|
||||
:type "number"
|
||||
:min "0"
|
||||
:value (:height shape)
|
||||
:on-change (partial on-size-change :height)}]]
|
||||
|
||||
[:span "Position"]
|
||||
[:div.row-flex
|
||||
[:input#width.input-text
|
||||
{:placeholder "x"
|
||||
:type "number"
|
||||
:value (:x shape "")
|
||||
:on-change (partial on-pos-change :x)}]
|
||||
[:input#width.input-text
|
||||
{:placeholder "y"
|
||||
:type "number"
|
||||
:value (:y shape "")
|
||||
:on-change (partial on-pos-change :y)}]]
|
||||
|
||||
[:span "Rotation"]
|
||||
[:div.row-flex
|
||||
[:input.slidebar
|
||||
{:type "range"
|
||||
:min 0
|
||||
:max 360
|
||||
:value (:rotation shape 0)
|
||||
:on-change on-rotation-change}]]
|
||||
|
||||
[:div.row-flex
|
||||
[:input#width.input-text
|
||||
{:placeholder ""
|
||||
:type "number"
|
||||
:min 0
|
||||
:max 360
|
||||
:value (:rotation shape "0")
|
||||
:on-change on-rotation-change
|
||||
}]
|
||||
[:input.input-text
|
||||
{:style {:visibility "hidden"}}]
|
||||
]]]
|
||||
)))
|
||||
|
||||
(defmethod -render-menu :menu/circle-measures
|
||||
[menu own shape]
|
||||
(letfn [(on-size-change [attr event]
|
||||
|
@ -270,18 +356,18 @@
|
|||
value (parse-int value 0)
|
||||
sid (:id shape)
|
||||
props {attr value}]
|
||||
#_(rs/emit! (dw/update-size sid props))))
|
||||
(rs/emit! (dw/update-radius-attrs sid props))))
|
||||
(on-rotation-change [event]
|
||||
(let [value (dom/event->value event)
|
||||
value (parse-int value 0)
|
||||
sid (:id shape)]
|
||||
#_(rs/emit! (dw/update-rotation sid value))))
|
||||
(rs/emit! (dw/update-rotation sid value))))
|
||||
(on-pos-change [attr event]
|
||||
(let [value (dom/event->value event)
|
||||
value (parse-int value nil)
|
||||
sid (:id shape)
|
||||
props {attr value}]
|
||||
#_(rs/emit! (dw/update-position sid props))))]
|
||||
(rs/emit! (dw/update-position sid props))))]
|
||||
(html
|
||||
[:div.element-set {:key (str (:id menu))}
|
||||
[:div.element-set-title (:name menu)]
|
||||
|
@ -309,12 +395,12 @@
|
|||
{:placeholder "cx"
|
||||
:type "number"
|
||||
:value (:cx shape "")
|
||||
:on-change (partial on-pos-change :cx)}]
|
||||
:on-change (partial on-pos-change :x)}]
|
||||
[:input#width.input-text
|
||||
{:placeholder "cy"
|
||||
:type "number"
|
||||
:value (:cy shape "")
|
||||
:on-change (partial on-pos-change :cy)}]]
|
||||
:on-change (partial on-pos-change :y)}]]
|
||||
|
||||
[:span "Rotation"]
|
||||
[:div.row-flex
|
||||
|
@ -351,7 +437,7 @@
|
|||
value (parse-int value nil)
|
||||
sid (:id shape)
|
||||
props {attr value}]
|
||||
(rs/emit! (dw/update-line sid props))))]
|
||||
(rs/emit! (dw/update-line-attrs sid props))))]
|
||||
(html
|
||||
[:div.element-set {:key (str (:id menu))}
|
||||
[:div.element-set-title (:name menu)]
|
||||
|
|
Loading…
Add table
Reference in a new issue