diff --git a/common/uxbox/common/data.cljc b/common/uxbox/common/data.cljc index e80e1c6a8..d1c4bb607 100644 --- a/common/uxbox/common/data.cljc +++ b/common/uxbox/common/data.cljc @@ -141,3 +141,7 @@ (if (or (nil? val) (nan? val)) default (str val))) + +(defn coalesce + [val default] + (or val default)) diff --git a/frontend/gulpfile.js b/frontend/gulpfile.js index 8fad08fdf..6f78562d7 100644 --- a/frontend/gulpfile.js +++ b/frontend/gulpfile.js @@ -20,7 +20,6 @@ const postcss = require('postcss') const paths = {}; paths.resources = "./resources/"; paths.output = "./resources/public/"; -paths.build = "./target/build/"; paths.dist = "./target/dist/"; paths.scss = "./resources/styles/**/*.scss"; diff --git a/frontend/resources/locales.json b/frontend/resources/locales.json index a894db5ae..7c3d16415 100644 --- a/frontend/resources/locales.json +++ b/frontend/resources/locales.json @@ -505,7 +505,7 @@ "fr" : "VOS IMAGES" } }, - "element.fill" : { + "workspace.options.fill" : { "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/fill.cljs:44" ], "translations" : { "en" : "Fill", @@ -1173,10 +1173,17 @@ "fr" : "Position" } }, - "workspace.options.rotation-radius" : { + "workspace.options.rotation" : { "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:114", "src/uxbox/main/ui/workspace/sidebar/options/icon.cljs:112", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:108", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:107", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:112" ], "translations" : { - "en" : "Rotation & Radius", + "en" : "Rotation", + "fr" : "TODO" + } + }, + "workspace.options.radius" : { + "used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:114", "src/uxbox/main/ui/workspace/sidebar/options/icon.cljs:112", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:108", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:107", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:112" ], + "translations" : { + "en" : "Radius", "fr" : "TODO" } }, diff --git a/frontend/resources/styles/common/framework.scss b/frontend/resources/styles/common/framework.scss index 3e5044150..3cfb82e03 100644 --- a/frontend/resources/styles/common/framework.scss +++ b/frontend/resources/styles/common/framework.scss @@ -330,8 +330,9 @@ ul.slider-dots { // Input elements .input-element { display: flex; + flex-shrink: 0; position: relative; - width: 100%; + width: 75px; &::after { color: $color-gray-20; @@ -756,7 +757,8 @@ input[type=checkbox]:checked + label{ input[type=range] { background-color: transparent; -webkit-appearance: none; - margin: 10px 0; + margin: 10px 0 10px 3px; + max-width: 70px; width: 100%; } input[type=range]:focus { @@ -764,7 +766,7 @@ input[type=range]:focus { } input[type=range]::-webkit-slider-runnable-track { width: 100%; - height: 8px; + height: 6px; cursor: pointer; animate: 0.2s; box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d; @@ -775,13 +777,13 @@ input[type=range]::-webkit-slider-runnable-track { input[type=range]::-webkit-slider-thumb { box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d; border: 0px solid #000000; - height: 24px; - width: 8px; + height: 18px; + width: 6px; border-radius: 7px; background: $color-gray-20; cursor: pointer; -webkit-appearance: none; - margin-top: -8px; + margin-top: -6px; } input[type=range]:focus::-webkit-slider-runnable-track { background: $color-gray-60; diff --git a/frontend/resources/styles/main/partials/colorpicker.scss b/frontend/resources/styles/main/partials/colorpicker.scss index bba8f1211..9ced54c58 100644 --- a/frontend/resources/styles/main/partials/colorpicker.scss +++ b/frontend/resources/styles/main/partials/colorpicker.scss @@ -154,16 +154,18 @@ .color-info { input { - border: 1px solid $color-gray-40; + background-color: $color-gray-50; + border: 1px solid $color-gray-30; border-radius: $br-small; - color: $color-gray-10; - margin: 3px 0 0 $x-small; + color: $color-gray-20; + height: 25px; + margin: 5px 0 0 0; padding: 0 $x-small; width: 58px; font-size: $fs13; &:focus { - border-color: $color-gray-10; + color: $color-white; } } } diff --git a/frontend/resources/styles/main/partials/sidebar-element-options.scss b/frontend/resources/styles/main/partials/sidebar-element-options.scss index 50d98d858..530d439f8 100644 --- a/frontend/resources/styles/main/partials/sidebar-element-options.scss +++ b/frontend/resources/styles/main/partials/sidebar-element-options.scss @@ -214,9 +214,10 @@ } } - span { + .element-set-subtitle { color: $color-gray-10; font-size: $fs12; + width: 12rem; } .lock-size { @@ -255,6 +256,7 @@ } .custom-select { + cursor: pointer; border: 1px solid $color-gray-40; padding: $x-small $big $x-small $x-small; position: relative; @@ -271,6 +273,10 @@ } } + span { + font-size: $fs13; + } + .custom-select-dropdown { position: absolute; left: 0; @@ -343,12 +349,12 @@ .color-th { background-color: $color-gray-lighter; - border: 1px solid $color-gray-40; + border: 1px solid $color-gray-10; border-radius: $br-small; cursor: pointer; flex-shrink: 0; height: 25px; - margin: 5px 4px 0 4px; + margin: 5px 4px 0 0; width: 25px; &.palette-th { @@ -436,10 +442,11 @@ margin-left: $small; svg { + cursor: pointer; + height: 20px; stroke: $color-gray-40; stroke-width: 30px; - height: 25px; - width: 25px; + width: 20px; } &:hover { diff --git a/frontend/src/uxbox/main/data/workspace.cljs b/frontend/src/uxbox/main/data/workspace.cljs index f31135aed..786f492d8 100644 --- a/frontend/src/uxbox/main/data/workspace.cljs +++ b/frontend/src/uxbox/main/data/workspace.cljs @@ -2284,7 +2284,7 @@ "ctrl+c" #(st/emit! copy-selected) "ctrl+v" #(st/emit! paste) "esc" #(st/emit! :interrupt deselect-all) - "delete" #(st/emit! delete-selected) + "del" #(st/emit! delete-selected) "ctrl+up" #(st/emit! (vertical-order-selected :up)) "ctrl+down" #(st/emit! (vertical-order-selected :down)) "ctrl+shift+up" #(st/emit! (vertical-order-selected :top)) diff --git a/frontend/src/uxbox/main/ui/shapes/frame.cljs b/frontend/src/uxbox/main/ui/shapes/frame.cljs index c2a85b36b..4e2e46088 100644 --- a/frontend/src/uxbox/main/ui/shapes/frame.cljs +++ b/frontend/src/uxbox/main/ui/shapes/frame.cljs @@ -61,15 +61,19 @@ (let [selected-iref (-> (mf/deps (:id shape)) (mf/use-memo #(refs/make-selected (:id shape)))) selected? (mf/deref selected-iref) - zoom (mf/deref refs/selected-zoom)] + zoom (mf/deref refs/selected-zoom) + frame-shape (mf/use-memo #(frame-shape shape-wrapper))] (when (and shape (not (:hidden shape))) (let [on-mouse-down #(common/on-mouse-down % shape) on-context-menu #(common/on-context-menu % shape) shape (merge frame-default-props shape) + {:keys [x y width height]} shape + inv-zoom (/ 1 zoom) childs (mapv #(get objects %) (:shapes shape)) ds-modifier (:displacement-modifier shape) + label-pos (cond-> (gpt/point x (- y 10)) (gmt/matrix? ds-modifier) (gpt/transform ds-modifier)) @@ -95,8 +99,8 @@ ;; User may also select the frame with single click in the label :on-click on-double-click} (:name shape)] - [:& (frame-shape shape-wrapper) {:shape shape - :childs childs}]]))))) + [:& frame-shape {:shape shape + :childs childs}]]))))) (defn frame-shape [shape-wrapper] diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs index 66adf94ef..bb46a548f 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs @@ -177,7 +177,7 @@ i/arrow-slide])] (when (and (:shapes item) (not collapsed?)) [:ul.element-children - (for [[index id] (d/enumerate (:shapes item))] + (for [[index id] (reverse (d/enumerate (:shapes item)))] (when-let [item (get objects id)] [:& layer-item {:item item @@ -194,7 +194,7 @@ objects (:objects data) root (get objects uuid/zero)] [:ul.element-list - (for [[index id] (d/enumerate (reverse (:shapes root)))] + (for [[index id] (reverse (d/enumerate (:shapes root)))] (let [item (get objects id)] [:& layer-item {:item item diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/circle.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/circle.cljs index 44ad5a51d..41eac204a 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/circle.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/circle.cljs @@ -2,8 +2,10 @@ ;; 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 -;; Copyright (c) 2015-2019 Andrey Antukh +;; This Source Code Form is "Incompatible With Secondary Licenses", as +;; defined by the Mozilla Public License, v. 2.0. +;; +;; Copyright (c) 2020 UXBOX Labs SL (ns uxbox.main.ui.workspace.sidebar.options.circle (:require @@ -17,12 +19,14 @@ [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 :as math :refer (precision-or-0)])) + [uxbox.util.i18n :as i18n :refer [tr t]] + [uxbox.util.math :as math])) (mf/defc measures-menu [{:keys [shape] :as props}] - (let [on-size-change + (let [locale (i18n/use-locale) + + on-size-change (fn [event attr] (let [value (-> (dom/get-target event) (dom/get-value) @@ -40,7 +44,7 @@ (fn [event attr] (let [value (-> (dom/get-target event) (dom/get-value) - (d/parse-integer))] + (d/parse-integer 0))] (st/emit! (udw/update-position (:id shape) {attr value})))) on-pos-cx-change #(on-position-change % :x) @@ -57,71 +61,83 @@ (fn [event] (let [value (-> (dom/get-target event) (dom/get-value) - (d/parse-double 0))] + (d/parse-integer 0))] (st/emit! (udw/update-shape (:id shape) {:rx value :ry value}))))] [:div.element-set - [:div.element-set-title (tr "workspace.options.measures")] [:div.element-set-content ;; SIZE - [:span (tr "workspace.options.size")] [:div.row-flex - [:div.input-element.pixels - [:input.input-text {:type "number" - :min "0" - :on-change on-size-rx-change - :value (-> (:rx shape) - (math/precision 2) - (d/coalesce-str "0"))}]] + [:span.element-set-subtitle (t locale "workspace.options.size")] [:div.lock-size {:class (when (:proportion-lock shape) "selected") :on-click on-proportion-lock-change} (if (:proportion-lock shape) i/lock i/unlock)] - + [:div.input-element.pixels + [:input.input-text {:type "number" + :min "0" + :on-change on-size-rx-change + :value (str (-> (:rx shape) + (d/coalesce 0) + (math/round)))}]] [:div.input-element.pixels [:input.input-text {:type "number" :min "0" :on-change on-size-ry-change - :value (-> (:ry shape) - (math/precision 2) - (d/coalesce-str "0"))}]]] + :value (str (-> (:ry shape) + (d/coalesce 0) + (math/round)))}]]] ;; POSITION - [:span (tr "workspace.options.position")] [:div.row-flex + [:span.element-set-subtitle (t locale "workspace.options.position")] [:div.input-element.pixels [:input.input-text {:type "number" :on-change on-pos-cx-change - :value (-> (:cx shape) - (math/precision 2) - (d/coalesce-str "0"))}]] + :value (str (-> (:cx shape) + (d/coalesce 0) + (math/round)))}]] [:div.input-element.pixels [:input.input-text {:type "number" :on-change on-pos-cy-change - :value (-> (:cy shape) - (math/precision 2) - (d/coalesce-str "0"))}]]] - ;; ROTATION & RADIUS - [:span (tr "workspace.options.rotation-radius")] - [:div.row-flex - [:div.input-element.degrees - [:input.input-text {:placeholder "" - :type "number" - :min 0 - :max 360 - :on-change on-rotation-change - :value (-> (:rotation shape) - (math/precision 2) - (d/coalesce-str "0"))}]] + :value (str (-> (:cy shape) + (d/coalesce 0) + (math/round)))}]]] + [:div.row-flex + [:span.element-set-subtitle (t locale "workspace.options.rotation")] + [:div.input-element.degrees + [:input.input-text + {:type "number" + :min "0" + :max "360" + :on-change on-rotation-change + :value (str (-> (:rotation shape) + (d/coalesce 0) + (math/round)))}]] + + [:input.slidebar + {:type "range" + :min "0" + :max "360" + :on-change on-rotation-change + :value (str (-> (:rotation shape) + (d/coalesce 0) + (math/round))) + :step "1"}]] + + [:div.row-flex + [:span.element-set-subtitle (t locale "workspace.options.radius")] [:div.input-element.pixels - [:input.input-text {:type "number" - :on-change on-radius-change - :value (-> (:rx shape) - (math/precision 2) - (d/coalesce-str "0"))}]]]]])) + [:input.input-text + {:type "number" + :on-change on-radius-change + :value (str (-> (:rx shape) + (d/coalesce 0) + (math/round)))}]] + [:div.input-element]]]])) (mf/defc options [{:keys [shape] :as props}] diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/fill.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/fill.cljs index c6de18aac..1364e659b 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/fill.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/fill.cljs @@ -2,8 +2,10 @@ ;; 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 Juan de la Cruz -;; Copyright (c) 2015-2019 Andrey Antukh +;; This Source Code Form is "Incompatible With Secondary Licenses", as +;; defined by the Mozilla Public License, v. 2.0. +;; +;; Copyright (c) 2020 UXBOX Labs SL (ns uxbox.main.ui.workspace.sidebar.options.fill (:require @@ -15,52 +17,66 @@ [uxbox.main.ui.modal :as modal] [uxbox.main.ui.workspace.colorpicker :refer [colorpicker-modal]] [uxbox.util.dom :as dom] - [uxbox.util.i18n :refer [tr]])) + [uxbox.util.math :as math] + [uxbox.util.i18n :as i18n :refer [tr t]])) (mf/defc fill-menu [{:keys [shape] :as props}] - (letfn [(update-shape! [attr value] - (st/emit! (udw/update-shape (:id shape) {attr value}))) - (on-color-change [event] - (let [value (-> (dom/get-target event) - (dom/get-value))] - (update-shape! :fill-color value))) - (on-opacity-change [event] - (let [value (-> (dom/get-target event) - (dom/get-value) - (d/parse-double 1) - (/ 10000))] - (update-shape! :fill-opacity value))) - (show-color-picker [event] - (let [x (.-clientX event) - y (.-clientY event) - props {:x x :y y - :on-change #(update-shape! :fill-color %) - :default "#ffffff" - :value (:fill-color shape) - :transparent? true}] - (modal/show! colorpicker-modal props)))] + (let [locale (i18n/use-locale) + + on-color-change + (fn [color] + (st/emit! (udw/update-shape (:id shape) {:fill-color color}))) + + on-opacity-change + (fn [event] + (let [value (-> (dom/get-target event) + (dom/get-value) + (d/parse-integer 1) + (/ 100))] + (st/emit! (udw/update-shape (:id shape) {:fill-opacity value})))) + + show-color-picker + (fn [event] + (let [x (.-clientX event) + y (.-clientY event) + props {:x x :y y + :on-change on-color-change + :default "#ffffff" + :value (:fill-color shape) + :transparent? true}] + (modal/show! colorpicker-modal props)))] + [:div.element-set - [:div.element-set-title (tr "element.fill")] + [:div.element-set-title (t locale "workspace.options.fill")] [:div.element-set-content - [:span (tr "workspace.options.color")] [:div.row-flex.color-data [:span.color-th - {:style {:background-color (:fill-color shape "#000000")} + {:style {:background-color (:fill-color shape)} :on-click show-color-picker}] - [:div.color-info - [:input - {:on-change on-color-change - :value (:fill-color shape "")}]]] - ;; SLIDEBAR FOR ROTATION AND OPACITY - [:span (tr "workspace.options.opacity")] - [:div.row-flex - [:input.slidebar - {:type "range" - :min "0" - :max "10000" - :value (str (* 10000 (:fill-opacity shape 1))) - :step "1" - :on-change on-opacity-change}]]]])) + [:div.color-info + [:input {:read-only true + :key (:fill-color shape) + :default-value (:fill-color shape)}]] + + [:div.input-element.percentail + [:input.input-text {:type "number" + :value (str (-> (:fill-opacity shape) + (d/coalesce 1) + (* 100) + (math/round))) + :on-change on-opacity-change + :min "0" + :max "100"}]] + + [:input.slidebar {:type "range" + :min "0" + :max "100" + :value (str (-> (:fill-opacity shape) + (d/coalesce 1) + (* 100) + (math/round))) + :step "1" + :on-change on-opacity-change}]]]])) diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/frame.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/frame.cljs index b2a5bed6c..d7c557bd0 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/frame.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/frame.cljs @@ -73,7 +73,6 @@ on-pos-y-change #(on-position-change % :y)] [:div.element-set - [:div.element-set-title (tr "workspace.options.measures")] [:div.element-set-content @@ -96,10 +95,15 @@ [:span.orientation-icon {on-click #(on-orientation-clicked :horiz)} i/size-horiz] ] - [:span (tr "workspace.options.size")] ;; WIDTH & HEIGHT [:div.row-flex + [:span.element-set-subtitle (tr "workspace.options.size")] + [:div.lock-size {:class (when (:proportion-lock shape) "selected") + :on-click on-proportion-lock-change} + (if (:proportion-lock shape) + i/lock + i/unlock)] [:div.input-element.pixels [:input.input-text {:type "number" :min "0" @@ -108,11 +112,6 @@ (math/precision 2) (d/coalesce-str "0"))}]] - [:div.lock-size {:class (when (:proportion-lock shape) "selected") - :on-click on-proportion-lock-change} - (if (:proportion-lock shape) - i/lock - i/unlock)] [:div.input-element.pixels [:input.input-text {:type "number" @@ -123,8 +122,8 @@ (d/coalesce-str "0"))}]]] ;; POSITION - [:span (tr "workspace.options.position")] [:div.row-flex + [:span.element-set-subtitle (tr "workspace.options.position")] [:div.input-element.pixels [:input.input-text {:placeholder "x" :type "number" diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/icon.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/icon.cljs index 7e0c81491..eb913474f 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/icon.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/icon.cljs @@ -20,12 +20,14 @@ [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.i18n :as i18n :refer [tr t]] [uxbox.util.math :as math])) (mf/defc measures-menu [{:keys [shape] :as props}] - (let [on-size-change + (let [locale (i18n/use-locale) + + on-size-change (fn [event attr] (let [value (-> (dom/get-target event) (dom/get-value) @@ -40,7 +42,7 @@ (fn [event attr] (let [value (-> (dom/get-target event) (dom/get-value) - (d/parse-integer))] + (d/parse-integer 0))] (st/emit! (udw/update-position (:id shape) {attr value})))) on-rotation-change @@ -54,7 +56,7 @@ (fn [event] (let [value (-> (dom/get-target event) (dom/get-value) - (d/parse-double 0))] + (d/parse-integer 0))] (st/emit! (udw/update-shape (:id shape) {:rx value :ry value})))) on-width-change #(on-size-change % :width) @@ -63,72 +65,89 @@ on-pos-y-change #(on-position-change % :y)] [:div.element-set - [:div.element-set-title (tr "workspace.options.measures")] [:div.element-set-content - [:span (tr "workspace.options.size")] ;; WIDTH & HEIGHT [:div.row-flex - [:div.input-element.pixels - [:input.input-text {:type "number" - :min "0" - :on-change on-width-change - :value (-> (:width shape) - (math/precision 2) - (d/coalesce-str "0"))}]] - + [:span.element-set-subtitle (t locale "workspace.options.size")] [:div.lock-size {:class (when (:proportion-lock shape) "selected") :on-click on-proportion-lock-change} (if (:proportion-lock shape) i/lock i/unlock)] + [:div.input-element.pixels + [:input.input-text {:type "number" + :min "0" + :no-validate true + :on-change on-width-change + :value (str (-> (:width shape) + (d/coalesce 0) + (math/round)))}]] + [:div.input-element.pixels [:input.input-text {:type "number" :min "0" + :no-validate true :on-change on-height-change - :value (-> (:height shape) - (math/precision 2) - (d/coalesce-str "0"))}]]] + :value (str (-> (:height shape) + (d/coalesce 0) + (math/round)))}]]] ;; POSITION - [:span (tr "workspace.options.position")] [:div.row-flex + [:span.element-set-subtitle (t locale "workspace.options.position")] [:div.input-element.pixels [:input.input-text {:placeholder "x" :type "number" + :no-validate true :on-change on-pos-x-change - :value (-> (:x shape) - (math/precision 2) - (d/coalesce-str "0"))}]] + :value (str (-> (:x shape) + (d/coalesce 0) + (math/round)))}]] [:div.input-element.pixels [:input.input-text {:placeholder "y" :type "number" + :no-validate true :on-change on-pos-y-change - :value (-> (:y shape) - (math/precision 2) - (d/coalesce-str "0"))}]]] + :value (str (-> (:y shape) + (d/coalesce 0) + (math/round)))}]]] - [:span (tr "workspace.options.rotation-radius")] [:div.row-flex + [:span.element-set-subtitle (t locale "workspace.options.rotation")] [:div.input-element.degrees - [:input.input-text {:placeholder "" - :type "number" - :min 0 - :max 360 - :on-change on-rotation-change - :value (-> (:rotation shape 0) - (math/precision 2) - (d/coalesce-str "0"))}]] + [:input.input-text + {:placeholder "" + :type "number" + :no-validate true + :min "0" + :max "360" + :on-change on-rotation-change + :value (str (-> (:rotation shape) + (d/coalesce 0) + (math/round)))}]] + [:input.slidebar + {:type "range" + :min "0" + :max "360" + :step "1" + :no-validate true + :on-change on-rotation-change + :value (str (-> (:rotation shape) + (d/coalesce 0)))}]] + [:div.row-flex + [:span.element-set-subtitle (t locale "workspace.options.radius")] [:div.input-element.pixels [:input.input-text {:placeholder "rx" :type "number" :on-change on-radius-change - :value (-> (:rx shape) - (math/precision 2) - (d/coalesce-str "0"))}]]]]])) + :value (str (-> (:rx shape) + (d/coalesce 0) + (math/round)))}]] + [:div.input-element]]]])) (mf/defc options diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/image.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/image.cljs index c6dc210d2..f130fc535 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/image.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/image.cljs @@ -15,12 +15,15 @@ [uxbox.main.store :as st] [uxbox.util.dom :as dom] [uxbox.util.geom.point :as gpt] - [uxbox.util.i18n :refer [tr]] + [uxbox.util.i18n :as i18n :refer [t]] [uxbox.util.math :as math])) + (mf/defc measures-menu [{:keys [shape] :as props}] - (let [on-size-change + (let [locale (i18n/use-locale) + + on-size-change (fn [event attr] (let [value (-> (dom/get-target event) (dom/get-value) @@ -35,9 +38,8 @@ (fn [event attr] (let [value (-> (dom/get-target event) (dom/get-value) - (d/parse-integer)) - point (gpt/point {attr value})] - (st/emit! (udw/update-position (:id shape) point)))) + (d/parse-integer 0))] + (st/emit! (udw/update-position (:id shape) {attr value})))) on-rotation-change (fn [event] @@ -50,7 +52,7 @@ (fn [event] (let [value (-> (dom/get-target event) (dom/get-value) - (d/parse-double 0))] + (d/parse-integer 0))] (st/emit! (udw/update-shape (:id shape) {:rx value :ry value})))) on-width-change #(on-size-change % :width) @@ -59,72 +61,89 @@ on-pos-y-change #(on-position-change % :y)] [:div.element-set - [:div.element-set-title (tr "workspace.options.measures")] [:div.element-set-content - [:span (tr "workspace.options.size")] ;; WIDTH & HEIGHT [:div.row-flex - [:div.input-element.pixels - [:input.input-text {:type "number" - :min "0" - :on-change on-width-change - :value (-> (:width shape) - (math/precision 2) - (d/coalesce-str "0"))}]] - + [:span.element-set-subtitle (t locale "workspace.options.size")] [:div.lock-size {:class (when (:proportion-lock shape) "selected") :on-click on-proportion-lock-change} (if (:proportion-lock shape) i/lock i/unlock)] + [:div.input-element.pixels + [:input.input-text {:type "number" + :min "0" + :no-validate true + :on-change on-width-change + :value (str (-> (:width shape) + (d/coalesce 0) + (math/round)))}]] + [:div.input-element.pixels [:input.input-text {:type "number" :min "0" + :no-validate true :on-change on-height-change - :value (-> (:height shape) - (math/precision 2) - (d/coalesce-str "0"))}]]] + :value (str (-> (:height shape) + (d/coalesce 0) + (math/round)))}]]] ;; POSITION - [:span (tr "workspace.options.position")] [:div.row-flex + [:span.element-set-subtitle (t locale "workspace.options.position")] [:div.input-element.pixels [:input.input-text {:placeholder "x" :type "number" + :no-validate true :on-change on-pos-x-change - :value (-> (:x shape) - (math/precision 2) - (d/coalesce-str "0"))}]] + :value (str (-> (:x shape) + (d/coalesce 0) + (math/round)))}]] [:div.input-element.pixels [:input.input-text {:placeholder "y" :type "number" + :no-validate true :on-change on-pos-y-change - :value (-> (:y shape) - (math/precision 2) - (d/coalesce-str "0"))}]]] + :value (str (-> (:y shape) + (d/coalesce 0) + (math/round)))}]]] - [:span (tr "workspace.options.rotation-radius")] [:div.row-flex + [:span.element-set-subtitle (t locale "workspace.options.rotation")] [:div.input-element.degrees - [:input.input-text {:placeholder "" - :type "number" - :min 0 - :max 360 - :on-change on-rotation-change - :value (-> (:rotation shape 0) - (math/precision 2) - (d/coalesce-str "0"))}]] + [:input.input-text + {:placeholder "" + :type "number" + :no-validate true + :min "0" + :max "360" + :on-change on-rotation-change + :value (str (-> (:rotation shape) + (d/coalesce 0) + (math/round)))}]] + [:input.slidebar + {:type "range" + :min "0" + :max "360" + :step "1" + :no-validate true + :on-change on-rotation-change + :value (str (-> (:rotation shape) + (d/coalesce 0)))}]] + [:div.row-flex + [:span.element-set-subtitle (t locale "workspace.options.radius")] [:div.input-element.pixels [:input.input-text {:placeholder "rx" :type "number" :on-change on-radius-change - :value (-> (:rx shape) - (math/precision 2) - (d/coalesce-str "0"))}]]]]])) + :value (str (-> (:rx shape) + (d/coalesce 0) + (math/round)))}]] + [:div.input-element]]]])) (mf/defc options diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/page.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/page.cljs index 325d43c9b..f7456ee73 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/page.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/page.cljs @@ -111,8 +111,8 @@ [:div.element-set [:div.element-set-title (tr "workspace.options.grid-options")] [:div.element-set-content - [:span (tr "workspace.options.size")] [:div.row-flex + [:span.element-set-subtitle (tr "workspace.options.size")] [:div.input-element.pixels [:input.input-text {:type "number" :value (:grid-x options) @@ -121,8 +121,8 @@ [:input.input-text {:type "number" :value (:grid-y options) :on-change on-y-change}]]] - [:span (tr "workspace.options.color")] [: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 diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/rect.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/rect.cljs index 118ffd7ba..1e694142b 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/rect.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/rect.cljs @@ -5,8 +5,7 @@ ;; This Source Code Form is "Incompatible With Secondary Licenses", as ;; defined by the Mozilla Public License, v. 2.0. ;; -;; Copyright (c) 2015-2020 Andrey Antukh -;; Copyright (c) 2015-2020 Juan de la Cruz +;; Copyright (c) 2020 UXBOX Labs SL (ns uxbox.main.ui.workspace.sidebar.options.rect (:require @@ -20,12 +19,14 @@ [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.i18n :as i18n :refer [tr t]] [uxbox.util.math :as math])) (mf/defc measures-menu [{:keys [shape] :as props}] - (let [on-size-change + (let [locale (i18n/use-locale) + + on-size-change (fn [event attr] (let [value (-> (dom/get-target event) (dom/get-value) @@ -40,7 +41,7 @@ (fn [event attr] (let [value (-> (dom/get-target event) (dom/get-value) - (d/parse-integer))] + (d/parse-integer 0))] (st/emit! (udw/update-position (:id shape) {attr value})))) on-rotation-change @@ -54,7 +55,7 @@ (fn [event] (let [value (-> (dom/get-target event) (dom/get-value) - (d/parse-double 0))] + (d/parse-integer 0))] (st/emit! (udw/update-shape (:id shape) {:rx value :ry value})))) on-width-change #(on-size-change % :width) @@ -63,72 +64,89 @@ on-pos-y-change #(on-position-change % :y)] [:div.element-set - [:div.element-set-title (tr "workspace.options.measures")] [:div.element-set-content - [:span (tr "workspace.options.size")] ;; WIDTH & HEIGHT [:div.row-flex - [:div.input-element.pixels - [:input.input-text {:type "number" - :min "0" - :on-change on-width-change - :value (-> (:width shape) - (math/precision 2) - (d/coalesce-str "0"))}]] - + [:span.element-set-subtitle (t locale "workspace.options.size")] [:div.lock-size {:class (when (:proportion-lock shape) "selected") :on-click on-proportion-lock-change} (if (:proportion-lock shape) i/lock i/unlock)] + [:div.input-element.pixels + [:input.input-text {:type "number" + :min "0" + :no-validate true + :on-change on-width-change + :value (str (-> (:width shape) + (d/coalesce 0) + (math/round)))}]] + [:div.input-element.pixels [:input.input-text {:type "number" :min "0" + :no-validate true :on-change on-height-change - :value (-> (:height shape) - (math/precision 2) - (d/coalesce-str "0"))}]]] + :value (str (-> (:height shape) + (d/coalesce 0) + (math/round)))}]]] ;; POSITION - [:span (tr "workspace.options.position")] [:div.row-flex + [:span.element-set-subtitle (t locale "workspace.options.position")] [:div.input-element.pixels [:input.input-text {:placeholder "x" :type "number" + :no-validate true :on-change on-pos-x-change - :value (-> (:x shape) - (math/precision 2) - (d/coalesce-str "0"))}]] + :value (str (-> (:x shape) + (d/coalesce 0) + (math/round)))}]] [:div.input-element.pixels [:input.input-text {:placeholder "y" :type "number" + :no-validate true :on-change on-pos-y-change - :value (-> (:y shape) - (math/precision 2) - (d/coalesce-str "0"))}]]] + :value (str (-> (:y shape) + (d/coalesce 0) + (math/round)))}]]] - [:span (tr "workspace.options.rotation-radius")] [:div.row-flex + [:span.element-set-subtitle (t locale "workspace.options.rotation")] [:div.input-element.degrees - [:input.input-text {:placeholder "" - :type "number" - :min 0 - :max 360 - :on-change on-rotation-change - :value (-> (:rotation shape 0) - (math/precision 2) - (d/coalesce-str "0"))}]] + [:input.input-text + {:placeholder "" + :type "number" + :no-validate true + :min "0" + :max "360" + :on-change on-rotation-change + :value (str (-> (:rotation shape) + (d/coalesce 0) + (math/round)))}]] + [:input.slidebar + {:type "range" + :min "0" + :max "360" + :step "1" + :no-validate true + :on-change on-rotation-change + :value (str (-> (:rotation shape) + (d/coalesce 0)))}]] + [:div.row-flex + [:span.element-set-subtitle (t locale "workspace.options.radius")] [:div.input-element.pixels [:input.input-text {:placeholder "rx" :type "number" :on-change on-radius-change - :value (-> (:rx shape) - (math/precision 2) - (d/coalesce-str "0"))}]]]]])) + :value (str (-> (:rx shape) + (d/coalesce 0) + (math/round)))}]] + [:div.input-element]]]])) (mf/defc options diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs index 02c15c016..8e53f5fa7 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs @@ -2,8 +2,10 @@ ;; 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 Juan de la Cruz -;; Copyright (c) 2015-2019 Andrey Antukh +;; This Source Code Form is "Incompatible With Secondary Licenses", as +;; defined by the Mozilla Public License, v. 2.0. +;; +;; Copyright (c) 2020 UXBOX Labs SL (ns uxbox.main.ui.workspace.sidebar.options.stroke (:require @@ -14,14 +16,14 @@ [uxbox.main.store :as st] [uxbox.main.ui.modal :as modal] [uxbox.main.ui.workspace.colorpicker :refer [colorpicker-modal]] - [uxbox.util.data :refer [parse-int parse-float read-string]] [uxbox.util.dom :as dom] - [uxbox.util.i18n :refer [tr]] + [uxbox.util.i18n :as i18n :refer [tr t]] [uxbox.util.math :as math])) (mf/defc stroke-menu [{:keys [shape] :as props}] - (let [show-options (not= (:stroke-style shape) :none) + (let [locale (i18n/use-locale) + show-options (not= (:stroke-style shape) :none) on-stroke-style-change (fn [event] @@ -34,15 +36,15 @@ (fn [event] (let [value (-> (dom/get-target event) (dom/get-value) - (d/parse-double 1))] + (d/parse-integer 0))] (st/emit! (udw/update-shape (:id shape) {:stroke-width value})))) on-stroke-opacity-change (fn [event] (let [value (-> (dom/get-target event) (dom/get-value) - (d/parse-double 1) - (/ 10000))] + (d/parse-integer 0) + (/ 100))] (st/emit! (udw/update-shape (:id shape) {:stroke-opacity value})))) show-color-picker @@ -56,50 +58,60 @@ :transparent? true}] (modal/show! colorpicker-modal props)))] + ;; COLLAPSED + ;; [:div.element-set + ;; [:div.element-set-title (tr "workspace.options.stroke")] + ;; [:div.add-page i/close]] + + ;; EXPANDED [:div.element-set - [:div.element-set-title (tr "workspace.options.stroke")] + [:div.element-set-title (t locale "workspace.options.stroke")] [:div.element-set-content + ;; Stroke Color + [:div.row-flex.color-data + [:span.color-th {:style {:background-color (:stroke-color shape)} + :on-click show-color-picker}] + [:div.color-info + [:input {:read-only true + :key (:stroke-color shape) + :default-value (:stroke-color shape)}]] + + [:div.input-element.percentail + [:input.input-text {:placeholder "" + :value (str (-> (:stroke-opacity shape) + (d/coalesce 1) + (* 100) + (math/round))) + :type "number" + :on-change on-stroke-opacity-change + :min "0" + :max "100"}]] + + [:input.slidebar {:type "range" + :min "0" + :max "100" + :value (str (-> (:stroke-opacity shape) + (d/coalesce 1) + (* 100) + (math/round))) + :step "1" + :on-change on-stroke-opacity-change}]] + ;; Stroke Style & Width - [:span (tr "workspace.options.stroke.style")] [:div.row-flex [:select#style.input-select {:value (pr-str (:stroke-style shape)) :on-change on-stroke-style-change} - [:option {:value ":none"} (tr "workspace.options.stroke.none")] - [:option {:value ":solid"} (tr "workspace.options.stroke.solid")] - [:option {:value ":dotted"} (tr "workspace.options.stroke.dotted")] - [:option {:value ":dashed"} (tr "workspace.options.stroke.dashed")] - [:option {:value ":mixed"} (tr "workspace.options.stroke.mixed")]] + [:option {:value ":none"} (t locale "workspace.options.stroke.none")] + [:option {:value ":solid"} (t locale "workspace.options.stroke.solid")] + [:option {:value ":dotted"} (t locale "workspace.options.stroke.dotted")] + [:option {:value ":dashed"} (t locale "workspace.options.stroke.dashed")] + [:option {:value ":mixed"} (t locale "workspace.options.stroke.mixed")]] - [:div.input-element {:class (when show-options "pixels")} - (when show-options - [:input.input-text {:type "number" - :min "0" - :value (-> (:stroke-width shape) - (math/precision 2) - (d/coalesce-str "1")) - :on-change on-stroke-width-change}])]] - - ;; Stroke Color - (when show-options - [:* - [:span (tr "workspace.options.color")] - - [:div.row-flex.color-data - [:span.color-th {:style {:background-color (:stroke-color shape)} - :on-click show-color-picker}] - [:div.color-info - [:input {:read-only true - :default-value (:stroke-color shape "")}]]] - - [:span (tr "workspace.options.opacity")] - - [:div.row-flex - [:input.slidebar {:type "range" + [:div.input-element.pixels + [:input.input-text {:type "number" :min "0" - :max "10000" - :value (-> (:stroke-opacity shape 1) - (* 10000) - (d/coalesce-str "1")) - :step "1" - :on-change on-stroke-opacity-change}]]])]])) + :value (str (-> (:stroke-width shape) + (d/coalesce 1) + (math/round))) + :on-change on-stroke-width-change}]]]]]))