mirror of
https://github.com/penpot/penpot.git
synced 2025-01-09 16:30:37 -05:00
Initial work on element options improvement.
This commit is contained in:
parent
3b4224586f
commit
3cf5a4a4cf
2 changed files with 219 additions and 22 deletions
|
@ -229,6 +229,17 @@
|
|||
(-apply-update [_ state]
|
||||
(update-in state [:shapes-by-id sid] sh/-move' [x y]))))
|
||||
|
||||
(defn update-line
|
||||
[sid props]
|
||||
(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 shape [:x1 :y1 :x2 :y2])]
|
||||
(update-in state [:shapes-by-id sid] sh/-initialize
|
||||
(merge props' props))))))
|
||||
|
||||
;; TODO: rename fill to "color" for consistency.
|
||||
|
||||
(defn update-shape-fill
|
||||
|
|
|
@ -13,27 +13,41 @@
|
|||
[uxbox.ui.workspace.base :as wb]
|
||||
[uxbox.util.data :refer (parse-int parse-float read-string)]))
|
||||
|
||||
(def +menus-map+
|
||||
{:builtin/icon [:menu/icon-measures :menu/fill :menu/stroke]
|
||||
:builtin/line [:menu/stroke]
|
||||
:builtin/rect [:menu/icon-measures :menu/stroke :menu/fill]
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Constants
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(def ^:static ^:private +menus-map+
|
||||
{:builtin/icon [:menu/rect-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 +menus-by-id+
|
||||
{:menu/icon-measures
|
||||
{:name "Size & position"
|
||||
:icon i/infocard
|
||||
:id :menu/icon-measures}
|
||||
(def ^:static ^:private +menus-by-id+
|
||||
{:menu/rect-measures
|
||||
{:name "Size, position & rotation"
|
||||
:icon i/infocard}
|
||||
|
||||
:menu/line-measures
|
||||
{:name "Size, position & rotation"
|
||||
:icon i/infocard}
|
||||
|
||||
:menu/circle-measures
|
||||
{:name "Size, position & rotation"
|
||||
:icon i/infocard}
|
||||
|
||||
:menu/fill
|
||||
{:name "Fill"
|
||||
:icon i/fill
|
||||
:id :menu/fill}
|
||||
:icon i/fill}
|
||||
|
||||
:menu/stroke
|
||||
{:name "Stroke"
|
||||
:icon i/stroke
|
||||
:id :menu/stroke}})
|
||||
:icon i/stroke}})
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Helpers
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn- viewportcoord->clientcoord
|
||||
[pageid viewport-x viewport-y]
|
||||
|
@ -49,6 +63,10 @@
|
|||
vy (- y 50)]
|
||||
(viewportcoord->clientcoord page vx vy)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Implementation
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defmulti -render-menu
|
||||
(fn [menu own shape] (:id menu)))
|
||||
|
||||
|
@ -102,11 +120,6 @@
|
|||
:on-change on-color-change}]]
|
||||
|
||||
(recent-colors shape #(change-stroke {:color %}))
|
||||
[:span "Border radius"]
|
||||
[:div.row-flex
|
||||
[:input.input-text {:type "text" :placeholder "rx"}]
|
||||
[:span.lock-size i/lock]
|
||||
[:input.input-text {:type "text" :placeholder "ry"}]]
|
||||
|
||||
;; SLIDEBAR FOR ROTATION AND OPACITY
|
||||
[:span "Opacity"]
|
||||
|
@ -161,7 +174,7 @@
|
|||
:step "0.0001"
|
||||
:on-change on-opacity-change}]]]])))
|
||||
|
||||
(defmethod -render-menu :menu/icon-measures
|
||||
(defmethod -render-menu :menu/rect-measures
|
||||
[menu own shape]
|
||||
(letfn [(on-size-change [attr event]
|
||||
(let [value (dom/event->value event)
|
||||
|
@ -179,7 +192,8 @@
|
|||
value (parse-int value nil)
|
||||
sid (:id shape)
|
||||
props {attr value}]
|
||||
(rs/emit! (dw/update-shape-position sid props))))]
|
||||
(rs/emit! (dw/update-shape-position sid props))))
|
||||
(on-border-change [attr event])]
|
||||
(html
|
||||
[:div.element-set {:key (str (:id menu))}
|
||||
[:div.element-set-title (:name menu)]
|
||||
|
@ -214,6 +228,19 @@
|
|||
:value (:y shape "")
|
||||
:on-change (partial on-pos-change :y)}]]
|
||||
|
||||
[:span "Border radius"]
|
||||
[:div.row-flex
|
||||
[:input#width.input-text
|
||||
{:placeholder "rx"
|
||||
:type "number"
|
||||
:value (:rx shape "")
|
||||
:on-change (partial on-border-change :rx)}]
|
||||
[:input#width.input-text
|
||||
{:placeholder "ry"
|
||||
:type "number"
|
||||
:value (:ry shape "")
|
||||
:on-change (partial on-border-change :ry)}]]
|
||||
|
||||
[:span "Rotation"]
|
||||
[:div.row-flex
|
||||
[:input.slidebar
|
||||
|
@ -221,7 +248,164 @@
|
|||
:min 0
|
||||
:max 360
|
||||
:value (:rotation shape 0)
|
||||
:on-change on-rotation-change}]]]])))
|
||||
: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]
|
||||
(let [value (dom/event->value event)
|
||||
value (parse-int value 0)
|
||||
sid (:id shape)
|
||||
props {attr value}]
|
||||
#_(rs/emit! (dw/update-shape-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-shape-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-shape-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 (:rx shape)
|
||||
:on-change (partial on-size-change :rx)}]
|
||||
[:div.lock-size i/lock]
|
||||
[:input#width.input-text
|
||||
{:placeholder "Height"
|
||||
:type "number"
|
||||
:min "0"
|
||||
:value (:ry shape)
|
||||
:on-change (partial on-size-change :ry)}]]
|
||||
|
||||
[:span "Position"]
|
||||
[:div.row-flex
|
||||
[:input#width.input-text
|
||||
{:placeholder "cx"
|
||||
:type "number"
|
||||
:value (:cx shape "")
|
||||
:on-change (partial on-pos-change :cx)}]
|
||||
[:input#width.input-text
|
||||
{:placeholder "cy"
|
||||
:type "number"
|
||||
:value (:cy shape "")
|
||||
:on-change (partial on-pos-change :cy)}]]
|
||||
|
||||
[: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/line-measures
|
||||
[menu own shape]
|
||||
(letfn [(on-rotation-change [event]
|
||||
(let [value (dom/event->value event)
|
||||
value (parse-int value 0)
|
||||
sid (:id shape)]
|
||||
(rs/emit! (dw/update-shape-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-line sid props))))]
|
||||
(html
|
||||
[:div.element-set {:key (str (:id menu))}
|
||||
[:div.element-set-title (:name menu)]
|
||||
[:div.element-set-content
|
||||
[:span "Position"]
|
||||
[:div.row-flex
|
||||
[:input#width.input-text
|
||||
{:placeholder "x1"
|
||||
:type "number"
|
||||
:value (:x1 shape "")
|
||||
:on-change (partial on-pos-change :x1)}]
|
||||
[:input#width.input-text
|
||||
{:placeholder "y1"
|
||||
:type "number"
|
||||
:value (:y1 shape "")
|
||||
:on-change (partial on-pos-change :y1)}]]
|
||||
|
||||
[:div.row-flex
|
||||
[:input#width.input-text
|
||||
{:placeholder "x2"
|
||||
:type "number"
|
||||
:value (:x2 shape "")
|
||||
:on-change (partial on-pos-change :x2)}]
|
||||
[:input#width.input-text
|
||||
{:placeholder "y2"
|
||||
:type "number"
|
||||
:value (:y2 shape "")
|
||||
:on-change (partial on-pos-change :y2)}]]
|
||||
|
||||
[: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"}}]
|
||||
]]]
|
||||
)))
|
||||
|
||||
|
||||
|
||||
(defn element-opts-render
|
||||
[own shape]
|
||||
|
@ -239,12 +423,14 @@
|
|||
[:ul.element-icons
|
||||
(for [menu-id (get +menus-map+ (:type shape))
|
||||
:let [menu (get +menus-by-id+ menu-id)
|
||||
menu (assoc menu :id menu-id)
|
||||
selected? (= active-menu menu-id)]]
|
||||
[:li#e-info {:on-click #(swap! local assoc :menu menu-id)
|
||||
:key (str "menu-" (:id menu))
|
||||
:class (when selected? "selected")}
|
||||
(:icon menu)])]
|
||||
(let [menu (get +menus-by-id+ active-menu)]
|
||||
(let [menu (get +menus-by-id+ active-menu)
|
||||
menu (assoc menu :id active-menu)]
|
||||
(-render-menu menu own shape))]))))
|
||||
|
||||
(def ^:static element-opts
|
||||
|
|
Loading…
Reference in a new issue