0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-03 04:49:03 -05:00

🚧 Initial work on options refactor.

This commit is contained in:
Andrey Antukh 2019-12-20 11:08:48 +01:00
parent f906945101
commit 90dbe70b9f
6 changed files with 360 additions and 149 deletions

View file

@ -16,96 +16,84 @@
[uxbox.main.store :as st]
[uxbox.main.refs :as refs]
[uxbox.main.ui.shapes.attrs :refer [shape-default-attrs]]
[uxbox.main.ui.workspace.sidebar.options.circle-measures :as options-circlem]
[uxbox.main.ui.workspace.sidebar.options.fill :as options-fill]
[uxbox.main.ui.workspace.sidebar.options.icon-measures :as options-iconm]
[uxbox.main.ui.workspace.sidebar.options.image-measures :as options-imagem]
[uxbox.main.ui.workspace.sidebar.options.interactions :as options-interactions]
[uxbox.main.ui.workspace.sidebar.options.page :as options-page]
[uxbox.main.ui.workspace.sidebar.options.rect-measures :as options-rectm]
[uxbox.main.ui.workspace.sidebar.options.stroke :as options-stroke]
[uxbox.main.ui.workspace.sidebar.options.text :as options-text]
[uxbox.main.ui.workspace.sidebar.options.rect :as rect]
[uxbox.main.ui.workspace.sidebar.options.circle :as circle]
[uxbox.main.ui.workspace.sidebar.options.page :as page]
;; [uxbox.main.ui.workspace.sidebar.options.circle-measures :as options-circlem]
;; [uxbox.main.ui.workspace.sidebar.options.fill :as options-fill]
;; [uxbox.main.ui.workspace.sidebar.options.icon-measures :as options-iconm]
;; [uxbox.main.ui.workspace.sidebar.options.image-measures :as options-imagem]
;; [uxbox.main.ui.workspace.sidebar.options.interactions :as options-interactions]
;; [uxbox.main.ui.workspace.sidebar.options.rect-measures :as options-rectm]
;; [uxbox.main.ui.workspace.sidebar.options.stroke :as options-stroke]
;; [uxbox.main.ui.workspace.sidebar.options.text :as options-text]
[uxbox.util.data :as data]
[uxbox.util.dom :as dom]
[uxbox.util.i18n :refer [tr]]))
;; --- Constants
(def ^:private +menus-map+
{:icon [::icon-measures ::fill ::stroke]
:rect [::rect-measures ::fill ::stroke]
:path [::fill ::stroke ::interactions]
:circle [::circle-measures ::fill ::stroke]
:text [::fill ::text]
:image [::image-measures]
::page [::page-measures ::page-grid-options]})
;; (def ^:private +menus-map+
;; {:icon [::icon-measures ::fill ::stroke]
;; :rect [::rect-measures ::fill ::stroke]
;; :path [::fill ::stroke ::interactions]
;; :circle [::circle-measures ::fill ::stroke]
;; :text [::fill ::text]
;; :image [::image-measures]
;; ::page [::page-measures ::page-grid-options]})
(def ^:private +menus+
[{:name "element.measures"
:id ::icon-measures
:icon i/infocard
:comp options-iconm/icon-measures-menu}
{:name "element.measures"
:id ::image-measures
:icon i/infocard
:comp options-imagem/image-measures-menu}
{:name "element.measures"
:id ::rect-measures
:icon i/infocard
:comp options-rectm/rect-measures-menu}
{:name "element.measures"
:id ::circle-measures
:icon i/infocard
:comp options-circlem/circle-measures-menu}
{:name "element.fill"
:id ::fill
:icon i/fill
:comp options-fill/fill-menu}
{:name "element.stroke"
:id ::stroke
:icon i/stroke
:comp options-stroke/stroke-menu}
{:name "element.text"
:id ::text
:icon i/text
:comp options-text/text-menu}
{:name "element.interactions"
:id ::interactions
:icon i/action
:comp options-interactions/interactions-menu}
{:name "element.page-measures"
:id ::page-measures
:icon i/page
:comp options-page/measures-menu}
{:name "element.page-grid-options"
:id ::page-grid-options
:icon i/grid
:comp options-page/grid-options-menu}])
;; (def ^:private +menus+
;; [{:name "element.measures"
;; :id ::icon-measures
;; :icon i/infocard
;; :comp options-iconm/icon-measures-menu}
;; {:name "element.measures"
;; :id ::image-measures
;; :icon i/infocard
;; :comp options-imagem/image-measures-menu}
;; {:name "element.measures"
;; :id ::rect-measures
;; :icon i/infocard
;; :comp options-rectm/rect-measures-menu}
;; {:name "element.measures"
;; :id ::circle-measures
;; :icon i/infocard
;; :comp options-circlem/circle-measures-menu}
;; {:name "element.fill"
;; :id ::fill
;; :icon i/fill
;; :comp options-fill/fill-menu}
;; {:name "element.stroke"
;; :id ::stroke
;; :icon i/stroke
;; :comp options-stroke/stroke-menu}
;; {:name "element.text"
;; :id ::text
;; :icon i/text
;; :comp options-text/text-menu}
;; {:name "element.interactions"
;; :id ::interactions
;; :icon i/action
;; :comp options-interactions/interactions-menu}])
(def ^:private +menus-by-id+
(data/index-by-id +menus+))
;; (def ^:private +menus-by-id+
;; (data/index-by-id +menus+))
;; --- Options
(mf/defc shape-options
[{:keys [shape-id] :as props}]
(let [shape-iref (mf/use-memo {:deps #js [shape-id]
(let [shape-iref (mf/use-memo {:deps #js [(str shape-id)]
:fn #(-> (l/in [:workspace-data :shapes-by-id shape-id])
(l/derive st/state))})
shape (mf/deref shape-iref)
menus (get +menus-map+ (:type shape))]
shape (mf/deref shape-iref)]
[:div
(for [mid menus]
(let [{:keys [comp] :as menu} (get +menus-by-id+ mid)]
[:& comp {:menu menu :shape shape :key mid}]))]))
(mf/defc page-options
[{:keys [page] :as props}]
(let [menus (get +menus-map+ ::page)]
[:div
(for [mid menus]
(let [{:keys [comp] :as menu} (get +menus-by-id+ mid)]
[:& comp {:menu menu :page page :key mid}]))]))
(case (:type shape)
:rect [:& rect/options {:shape shape}]
:circle [:& circle/options {:shape shape}]
nil)]))
(mf/defc options-toolbox
{:wrap [mf/wrap-memo]}
@ -121,4 +109,4 @@
[:div.element-options
(if (= (count selected) 1)
[:& shape-options {:shape-id (first selected)}]
[:& page-options {:page page}])]]]))
[:& page/options {:page page}])]]]))

View file

@ -0,0 +1,133 @@
;; 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) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
;; Copyright (c) 2015-2019 Andrey Antukh <niwi@niwi.nz>
(ns uxbox.main.ui.workspace.sidebar.options.circle
(:require
[rumext.alpha :as mf]
[uxbox.builtins.icons :as i]
[uxbox.main.data.workspace :as udw]
[uxbox.main.geom :as geom]
[uxbox.main.store :as st]
[uxbox.main.ui.workspace.sidebar.options.fill :refer [fill-menu]]
[uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-menu]]
[uxbox.util.data :refer (parse-int parse-float read-string)]
[uxbox.util.dom :as dom]
[uxbox.util.geom.point :as gpt]
[uxbox.util.i18n :refer (tr)]
[uxbox.util.math :refer (precision-or-0)]))
(mf/defc size-options
[{:keys [shape] :as props}]
[:*
[:span (tr "ds.size")]
[:div.row-flex
[:div.input-element.pixels
[:input.input-text {:placeholder (tr "ds.width")
:type "number"
:min "0"
;; :on-change #(on-size-change % shape :rx)
:value (precision-or-0 (:rx shape 0) 2)}]]
[:div.lock-size {:class (when (:proportion-lock shape) "selected")
;; :on-click #(on-proportion-lock-change % shape)
}
(if (:proportion-lock shape) i/lock i/unlock)]
[:div.input-element.pixels
[:input.input-text
{:placeholder (tr "ds.height")
:type "number"
:min "0"
;; :on-change #(on-size-change % shape :ry)
:value (precision-or-0 (:ry shape 0) 2)}]]]])
(mf/defc position-options
[{:keys [shape] :as props}]
[:*
[:span (tr "ds.position")]
[:div.row-flex
[:div.input-element.pixels
[:input.input-text
{:placeholder "cx"
:type "number"
;; :on-change #(on-position-change % shape :x)
:value (precision-or-0 (:cx shape 0) 2)}]]
[:div.input-element.pixels
[:input.input-text
{:placeholder "cy"
:type "number"
;; :on-change #(on-position-change % shape :y)
:value (precision-or-0 (:cy shape 0) 2)}]]]])
(mf/defc rotation-options
[{:keys [shape] :as props}]
[:*
[:span (tr "ds.rotation")]
[:div.row-flex
[:input.slidebar
{:type "range"
:min 0
:max 360
;; :on-change #(on-rotation-change % shape)
:value (:rotation shape 0)}]]
[:div.row-flex
[:div.input-element.degrees
[:input.input-text
{:placeholder ""
:type "number"
:min 0
:max 360
;; :on-change #(on-rotation-change % shape)
:value (precision-or-0 (:rotation shape 0) 2)}]]
[:input.input-text
{:style {:visibility "hidden"}}]]])
(mf/defc measures-options
[{:keys [shape] :as props}]
[:div.element-set
[:div.element-set-title (tr "element.measures")]
[:div.element-set-content
[:& size-options {:shape shape}]
[:& position-options {:shape shape}]
[:& rotation-options {:shape shape}]]])
;; (defn- on-size-change
;; [event shape attr]
;; (let [value (dom/event->value event)
;; value (parse-int value 0)
;; sid (:id shape)
;; props {attr value}]
;; (st/emit! (udw/update-dimensions sid props))))
;; (defn- on-rotation-change
;; [event shape]
;; (let [value (dom/event->value event)
;; value (parse-int value 0)
;; sid (:id shape)]
;; (st/emit! (udw/update-shape-attrs sid {:rotation value}))))
;; (defn- on-position-change
;; [event shape attr]
;; (let [value (dom/event->value event)
;; value (parse-int value nil)
;; sid (:id shape)
;; point (gpt/point {attr value})]
;; (st/emit! (udw/update-position sid point))))
;; (defn- on-proportion-lock-change
;; [event shape]
;; (if (:proportion-lock shape)
;; (st/emit! (udw/unlock-proportions (:id shape)))
;; (st/emit! (udw/lock-proportions (:id shape)))))
(mf/defc options
[{:keys [shape] :as props}]
[:div
[:& measures-options {:shape shape}]
[:& fill-menu {:shape shape}]
[:& stroke-menu {:shape shape}]])

View file

@ -18,7 +18,7 @@
[uxbox.util.i18n :refer [tr]]))
(mf/defc fill-menu
[{:keys [menu shape]}]
[{:keys [shape] :as props}]
(letfn [(change-attrs [attrs]
(st/emit! (udw/update-shape-attrs (:id shape) attrs)))
(on-color-change [event]
@ -39,7 +39,7 @@
:transparent? true}]
(modal/show! colorpicker-modal props)))]
[:div.element-set
[:div.element-set-title (:name menu)]
[:div.element-set-title (tr "element.fill")]
[:div.element-set-content
[:span (tr "ds.color")]

View file

@ -22,79 +22,44 @@
[uxbox.util.i18n :refer [tr]]
[uxbox.util.spec :refer [color?]]))
(mf/defc measures-menu
[{:keys [menu page] :as props}]
(mf/defc metadata-options
[{:keys [page] :as props}]
(let [metadata (:metadata page)
metadata (merge c/page-metadata metadata)]
(letfn [(on-size-change [event attr]
#_(let [value (-> (dom/event->value event)
(parse-int nil))]
(st/emit! (->> (assoc metadata attr value)
(udp/update-metadata (:id page))))))
change-color
(fn [color]
#_(st/emit! (->> (assoc metadata :background color)
(udp/update-metadata (:id page)))))
on-color-change
(fn [event]
(let [value (dom/event->value event)]
(change-color value)))
(change-color [color]
#_(st/emit! (->> (assoc metadata :background color)
(udp/update-metadata (:id page)))))
show-color-picker
(fn [event]
(let [x (.-clientX event)
y (.-clientY event)
props {:x x :y y
:default "#ffffff"
:value (:background metadata)
:transparent? true
:on-change change-color}]
(modal/show! colorpicker-modal props)))]
(on-color-change [event]
(let [value (dom/event->value event)]
(change-color value)))
[:div.element-set
[:div.element-set-title (tr "element.page-measures")]
[:div.element-set-content
[:span (tr "ds.background-color")]
[:div.row-flex.color-data
[:span.color-th
{:style {:background-color (:background metadata "#ffffff")}
:on-click show-color-picker}]
[:div.color-info
[:input
{:on-change on-color-change
:value (:background metadata "#ffffff")}]]]]]))
(on-name-change [event]
#_(let [value (-> (dom/event->value event)
(str/trim))]
(st/emit! (-> (assoc page :name value)
(udp/update-page-attrs)))))
(show-color-picker [event]
(let [x (.-clientX event)
y (.-clientY event)
props {:x x :y y
:default "#ffffff"
:value (:background metadata)
:transparent? true
:on-change change-color}]
(modal/show! colorpicker-modal props)))]
[:div.element-set
[:div.element-set-title (tr (:name menu))]
[:div.element-set-content
[:span (tr "ds.name")]
[:div.row-flex
[:div.input-element
[:input.input-text
{:type "text"
:on-change on-name-change
:value (str (:name page))
:placeholder "page name"}]]]
[:span (tr "ds.size")]
[:div.row-flex
[:div.input-element.pixels
[:input.input-text
{:type "number"
:on-change #(on-size-change % :width)
:value (str (:width metadata))
:placeholder (tr "ds.width")}]]
[:div.input-element.pixels
[:input.input-text
{:type "number"
:on-change #(on-size-change % :height)
:value (str (:height metadata))
:placeholder (tr "ds.height")}]]]
[:span (tr "ds.background-color")]
[:div.row-flex.color-data
[:span.color-th
{:style {:background-color (:background metadata)}
:on-click show-color-picker}]
[:div.color-info
[:input
{:on-change on-color-change
:value (:background metadata)}]]]]])))
(mf/defc grid-options-menu
[{:keys [menu page] :as props}]
(mf/defc grid-options
[{:keys [page] :as props}]
(let [metadata (:metadata page)
metadata (merge c/page-metadata metadata)]
(letfn [(on-x-change [event]
@ -125,7 +90,7 @@
:on-change change-color}]
(modal/show! colorpicker-modal props)))]
[:div.element-set
[:div.element-set-title (tr (:name menu))]
[:div.element-set-title (tr "element.page-grid-options")]
[:div.element-set-content
[:span (tr "ds.size")]
[:div.row-flex
@ -150,3 +115,10 @@
[:input
{:on-change on-color-change
:value (:grid-color metadata "#cccccc")}]]]]])))
(mf/defc options
[{:keys [page] :as props}]
[:div
[:& metadata-options {:page page}]
[:& grid-options {:page page}]])

View file

@ -0,0 +1,118 @@
;; 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) 2015-2017 Andrey Antukh <niwi@niwi.nz>
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
(ns uxbox.main.ui.workspace.sidebar.options.rect
(:require
[rumext.alpha :as mf]
[uxbox.builtins.icons :as i]
[uxbox.main.data.workspace :as udw]
[uxbox.main.geom :as geom]
[uxbox.main.store :as st]
[uxbox.util.data :refer [parse-int parse-float read-string]]
[uxbox.main.ui.workspace.sidebar.options.fill :refer [fill-menu]]
[uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-menu]]
[uxbox.util.dom :as dom]
[uxbox.util.geom.point :as gpt]
[uxbox.util.i18n :refer [tr]]
[uxbox.util.math :refer [precision-or-0]]))
(declare on-size-change)
(declare on-rotation-change)
(declare on-position-change)
(declare on-proportion-lock-change)
(mf/defc measures
[{:keys [menu shape] :as props}]
(let [size (geom/size shape)]
[:div.element-set
[:div.element-set-title (tr "element.measures")]
[:div.element-set-content
[:span (tr "ds.size")]
;; WIDTH & HEIGHT
[:div.row-flex
[:div.input-element.pixels
[:input.input-text {:placeholder (tr "ds.width")
:type "number"
:min "0"
:value (precision-or-0 (:width size) 2)}]]
[:div.lock-size {:class (when (:proportion-lock shape) "selected")
:on-click #(on-proportion-lock-change % shape)}
(if (:proportion-lock shape) i/lock i/unlock)]
[:div.input-element.pixels
[:input.input-text {:placeholder (tr "ds.height")
:type "number"
:min "0"
:value (precision-or-0 (:height size) 2)}]]]
;; POSITION
[:span (tr "ds.position")]
[:div.row-flex
[:div.input-element.pixels
[:input.input-text {:placeholder "x"
:type "number"
:value (precision-or-0 (:x1 shape 0) 2)}]]
[:div.input-element.pixels
[:input.input-text {:placeholder "y"
:type "number"
:value (precision-or-0 (:y1 shape 0) 2)}]]]
;; ROTATION
[:span (tr "ds.rotation")]
[:div.row-flex
[:input.slidebar {:type "range"
:min 0
:max 360
;; :on-change #(on-rotation-change % shape)
:value (:rotation shape 0)}]]
[:div.row-flex
[:div.input-element.degrees
[:input.input-text {:placeholder ""
:type "number"
:min 0
:max 360
:on-change #(on-rotation-change % shape)
:value (precision-or-0 (:rotation shape "0") 2)}]]
[:input.input-text {:style {:visibility "hidden"}}]]]]))
;; (defn- on-size-change
;; [event shape attr]
;; (let [value (-> (dom/event->value event)
;; (parse-int 0))]
;; (st/emit! (udw/update-dimensions (:id shape) {attr value}))))
;; (defn- on-rotation-change
;; [event shape]
;; (let [value (dom/event->value event)
;; value (parse-int value 0)]
;; (st/emit! (udw/update-shape-attrs (:id shape) {:rotation value}))))
;; (defn- on-position-change
;; [event shape attr]
;; (let [value (-> (dom/event->value event)
;; (parse-int nil))
;; point (gpt/point {attr value})]
;; (st/emit! (udw/update-position (:id shape) point))))
;; (defn- on-proportion-lock-change
;; [event shape]
;; (if (:proportion-lock shape)
;; (st/emit! (udw/unlock-proportions (:id shape)))
;; (st/emit! (udw/lock-proportions (:id shape)))))
;; :rect [::rect-measures ::fill ::stroke]
(mf/defc options
[{:keys [shape] :as props}]
[:div
[:& measures {:shape shape}]
[:& fill-menu {:shape shape}]
[:& stroke-menu {:shape shape}]])

View file

@ -26,7 +26,7 @@
(declare show-color-picker)
(mf/defc stroke-menu
[{:keys [menu shape] :as props}]
[{:keys [shape] :as props}]
(let [local (mf/use-state {})
on-border-lock #(swap! local update :border-lock not)
on-stroke-style-change #(on-stroke-style-change % shape)
@ -37,7 +37,7 @@
on-opacity-change #(on-opacity-change % shape)
show-color-picker #(show-color-picker % shape)]
[:div.element-set
[:div.element-set-title (:name menu)]
[:div.element-set-title (tr "element.stroke")]
[:div.element-set-content
[:span (tr "ds.style")]
[:div.row-flex