diff --git a/CHANGES.md b/CHANGES.md index 50148ceb4..455b4882e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ - Duplicate and move files and projects [Taiga #267](https://tree.taiga.io/project/penpot/us/267) - Import SVG will create Penpot's shapes - Improve french translations [#731](https://github.com/penpot/penpot/pull/731) +- Add layer opacity and blend mode to shapes ### :bug: Bugs fixed diff --git a/common/app/common/data.cljc b/common/app/common/data.cljc index c661194e0..bc3d14dba 100644 --- a/common/app/common/data.cljc +++ b/common/app/common/data.cljc @@ -394,13 +394,15 @@ (defn name "Improved version of name that won't fail if the input is not a keyword" - [maybe-keyword] - (cond - (keyword? maybe-keyword) - (core/name maybe-keyword) + ([maybe-keyword] (name maybe-keyword nil)) + ([maybe-keyword default-value] + (cond + (keyword? maybe-keyword) + (core/name maybe-keyword) - (nil? maybe-keyword) nil + (nil? maybe-keyword) default-value - :else - (str maybe-keyword))) + :else + (or default-value + (str maybe-keyword))))) diff --git a/frontend/resources/locales.json b/frontend/resources/locales.json index 02498fc18..294d0bffd 100644 --- a/frontend/resources/locales.json +++ b/frontend/resources/locales.json @@ -5545,5 +5545,140 @@ "zh_cn" : "居中" }, "permanent": true + }, + + "workspace.options.layer-options.blend-mode.color" : { + "translations" : { + "en" : "Color", + "es" : "Color" + }, + "used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ] + }, + + "workspace.options.layer-options.blend-mode.color-burn" : { + "translations" : { + "en" : "Color burn", + "es" : "Color más oscuro" + }, + "used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ] + }, + "workspace.options.layer-options.blend-mode.color-dodge" : { + "translations" : { + "en" : "Color dodge", + "es" : "Color más suave" + }, + "used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ] + }, + "workspace.options.layer-options.blend-mode.darken" : { + "translations" : { + "en" : "Darken", + "es" : "Oscurecer" + }, + "used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ] + }, + "workspace.options.layer-options.blend-mode.difference" : { + "translations" : { + "en" : "Difference", + "es" : "Diferencia" + }, + "used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ] + }, + "workspace.options.layer-options.blend-mode.exclusion" : { + "translations" : { + "en" : "Exclusion", + "en" : "Exclusión" + }, + "used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ] + }, + "workspace.options.layer-options.blend-mode.hard-light" : { + "translations" : { + "en" : "Hard light", + "es" : "Luz fuerte" + }, + "used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ] + }, + "workspace.options.layer-options.blend-mode.hue" : { + "translations" : { + "en" : "Hue", + "es" : "Tono" + }, + "used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ] + }, + "workspace.options.layer-options.blend-mode.lighten" : { + "translations" : { + "en" : "Lighten", + "es" : "Aclarar" + }, + "used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ] + }, + "workspace.options.layer-options.blend-mode.luminosity" : { + "translations" : { + "en" : "Luminosity", + "es" : "Luminosidad" + }, + "used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ] + }, + "workspace.options.layer-options.blend-mode.multiply" : { + "translations" : { + "en" : "Multiply", + "es" : "Multiplicar" + }, + "used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ] + }, + "workspace.options.layer-options.blend-mode.normal" : { + "translations" : { + "en" : "Normal", + "es" : "Normal" + }, + "used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ] + }, + "workspace.options.layer-options.blend-mode.overlay" : { + "translations" : { + "en" : "Overlay", + "en" : "Superponer" + }, + "used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ] + }, + "workspace.options.layer-options.blend-mode.saturation" : { + "translations" : { + "en" : "Saturation", + "es" : "Saturación" + }, + "used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ] + }, + "workspace.options.layer-options.blend-mode.screen" : { + "translations" : { + "en" : "Screen", + "en" : "Trama" + }, + "used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ] + }, + "workspace.options.layer-options.blend-mode.soft-light" : { + "translations" : { + "en" : "Soft light", + "es" : "Luz suave" + }, + "used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ] + }, + "workspace.options.layer-options.title" : { + "translations" : { + "en" : "Layer", + "es" : "Capa" + }, + "used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ] + }, + "workspace.options.layer-options.title.group" : { + "translations" : { + "en" : "Group layers", + "es" : "Capas de grupo" + }, + "used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ] + }, + "workspace.options.layer-options.title.multiple" : { + "translations" : { + "en" : "Selected layers", + "es" : "Capas seleccionadas" + }, + "used-in" : [ "src/app/main/ui/workspace/sidebar/options/menus/layer.cljs" ] } } diff --git a/frontend/resources/styles/main/partials/sidebar-element-options.scss b/frontend/resources/styles/main/partials/sidebar-element-options.scss index 52dc12400..90e2b8f66 100644 --- a/frontend/resources/styles/main/partials/sidebar-element-options.scss +++ b/frontend/resources/styles/main/partials/sidebar-element-options.scss @@ -910,14 +910,16 @@ .element-set-actions { display: flex; visibility: hidden; - } .row-flex-removable:hover .element-set-actions, .element-set-options-group:hover .element-set-actions { - visibility: visible; + visibility: visible; } +.layer-actions { + visibility: visible; +} .typography-entry { margin: 0.5rem 0.3rem; diff --git a/frontend/src/app/main/data/workspace/svg_upload.cljs b/frontend/src/app/main/data/workspace/svg_upload.cljs index baea021f4..cb4c95563 100644 --- a/frontend/src/app/main/data/workspace/svg_upload.cljs +++ b/frontend/src/app/main/data/workspace/svg_upload.cljs @@ -96,6 +96,25 @@ (merge {:stroke-style :svg} shape) shape))) +(defn setup-opacity [shape] + (cond-> shape + (get-in shape [:svg-attrs :opacity]) + (-> (update :svg-attrs dissoc :opacity) + (assoc :opacity (get-in shape [:svg-attrs :opacity]))) + + (get-in shape [:svg-attrs :style :opacity]) + (-> (update-in [:svg-attrs :style] dissoc :opacity) + (assoc :opacity (get-in shape [:svg-attrs :style :opacity]))) + + + (get-in shape [:svg-attrs :mix-blend-mode]) + (-> (update :svg-attrs dissoc :mix-blend-mode) + (assoc :blend-mode (-> (get-in shape [:svg-attrs :mix-blend-mode]) keyword))) + + (get-in shape [:svg-attrs :style :mix-blend-mode]) + (-> (update-in [:svg-attrs :style] dissoc :mix-blend-mode) + (assoc :blend-mode (-> (get-in shape [:svg-attrs :style :mix-blend-mode]) keyword))))) + (defn create-raw-svg [name frame-id svg-data {:keys [attrs] :as data}] (let [{:keys [x y width height offset-x offset-y]} svg-data] (-> {:id (uuid/next) diff --git a/frontend/src/app/main/ui/handoff/exports.cljs b/frontend/src/app/main/ui/handoff/exports.cljs index 43d3c649a..f30948cca 100644 --- a/frontend/src/app/main/ui/handoff/exports.cljs +++ b/frontend/src/app/main/ui/handoff/exports.cljs @@ -18,7 +18,7 @@ [app.util.dom :as dom] [app.main.store :as st] [app.main.data.messages :as dm] - [app.main.ui.workspace.sidebar.options.exports :as we])) + [app.main.ui.workspace.sidebar.options.menus.exports :as we])) (mf/defc exports [{:keys [shape page-id file-id] :as props}] diff --git a/frontend/src/app/main/ui/shapes/attrs.cljs b/frontend/src/app/main/ui/shapes/attrs.cljs index 9d61e85a0..a2b97fb97 100644 --- a/frontend/src/app/main/ui/shapes/attrs.cljs +++ b/frontend/src/app/main/ui/shapes/attrs.cljs @@ -11,6 +11,7 @@ (:require [rumext.alpha :as mf] [cuerdas.core :as str] + [app.common.data :as d] [app.util.object :as obj] [app.main.ui.context :as muc] [app.util.svg :as usvg])) @@ -86,7 +87,7 @@ ;; If contains svg-attrs the origin is svg. If it's not svg origin ;; we setup the default fill as transparent (instead of black) (and (not (contains? shape :svg-attrs)) - (not (= :svg-raw (:type shape)))) + (not (#{ :svg-raw :group } (:type shape)))) {:fill "transparent"} :else @@ -120,6 +121,14 @@ (obj/merge! attrs (clj->js stroke-attrs))) attrs))) +(defn add-layer-props [attrs shape] + (cond-> attrs + (:opacity shape) + (obj/set! "opacity" (:opacity shape)) + + (and (:blend-mode shape) (not= (:blend-mode shape) :normal)) + (obj/set! "mixBlendMode" (d/name (:blend-mode shape))))) + (defn extract-svg-attrs [render-id svg-defs svg-attrs] (let [replace-id (fn [id] @@ -147,7 +156,8 @@ styles (-> (obj/new) (obj/merge! svg-styles) (add-fill shape render-id) - (add-stroke shape render-id))] + (add-stroke shape render-id) + (add-layer-props shape))] (-> (obj/new) (obj/merge! svg-attrs) diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs index ed043bf1c..665261936 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs @@ -31,7 +31,7 @@ [app.main.ui.components.tab-container :refer [tab-container tab-element]] [app.main.ui.context :as ctx] [app.main.ui.icons :as i] - [app.main.ui.workspace.sidebar.options.typography :refer [typography-entry]] + [app.main.ui.workspace.sidebar.options.menus.typography :refer [typography-entry]] [app.util.data :refer [matches-search]] [app.util.dom :as dom] [app.util.dom.dnd :as dnd] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options.cljs b/frontend/src/app/main/ui/workspace/sidebar/options.cljs index 571e76de7..a623cf933 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options.cljs @@ -17,19 +17,18 @@ [app.main.ui.context :as ctx] [app.main.ui.icons :as i] [app.main.ui.workspace.sidebar.align :refer [align-options]] - [app.main.ui.workspace.sidebar.options.circle :as circle] - [app.main.ui.workspace.sidebar.options.exports :refer [exports-menu]] - [app.main.ui.workspace.sidebar.options.frame :as frame] - [app.main.ui.workspace.sidebar.options.group :as group] - [app.main.ui.workspace.sidebar.options.icon :as icon] - [app.main.ui.workspace.sidebar.options.image :as image] - [app.main.ui.workspace.sidebar.options.interactions :refer [interactions-menu]] - [app.main.ui.workspace.sidebar.options.multiple :as multiple] + [app.main.ui.workspace.sidebar.options.menus.exports :refer [exports-menu]] + [app.main.ui.workspace.sidebar.options.menus.interactions :refer [interactions-menu]] [app.main.ui.workspace.sidebar.options.page :as page] - [app.main.ui.workspace.sidebar.options.path :as path] - [app.main.ui.workspace.sidebar.options.rect :as rect] - [app.main.ui.workspace.sidebar.options.text :as text] - [app.main.ui.workspace.sidebar.options.svg-raw :as svg-raw] + [app.main.ui.workspace.sidebar.options.shapes.circle :as circle] + [app.main.ui.workspace.sidebar.options.shapes.frame :as frame] + [app.main.ui.workspace.sidebar.options.shapes.group :as group] + [app.main.ui.workspace.sidebar.options.shapes.image :as image] + [app.main.ui.workspace.sidebar.options.shapes.multiple :as multiple] + [app.main.ui.workspace.sidebar.options.shapes.path :as path] + [app.main.ui.workspace.sidebar.options.shapes.rect :as rect] + [app.main.ui.workspace.sidebar.options.shapes.svg-raw :as svg-raw] + [app.main.ui.workspace.sidebar.options.shapes.text :as text] [app.util.i18n :as i18n :refer [tr t]] [app.util.object :as obj] [beicon.core :as rx] @@ -46,7 +45,6 @@ :group [:& group/options {:shape shape :shape-with-children shapes-with-children}] :text [:& text/options {:shape shape}] :rect [:& rect/options {:shape shape}] - :icon [:& icon/options {:shape shape}] :circle [:& circle/options {:shape shape}] :path [:& path/options {:shape shape}] :image [:& image/options {:shape shape}] @@ -106,4 +104,3 @@ :page-id page-id :section section}])) - diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/icon.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/icon.cljs deleted file mode 100644 index bba70abef..000000000 --- a/frontend/src/app/main/ui/workspace/sidebar/options/icon.cljs +++ /dev/null @@ -1,32 +0,0 @@ -;; 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/. -;; -;; 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 app.main.ui.workspace.sidebar.options.icon - (:require - [rumext.alpha :as mf] - [app.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]] - [app.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]] - [app.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]])) - -(mf/defc options - [{:keys [shape] :as props}] - (let [ids [(:id shape)] - type (:type shape) - measure-values (select-keys shape measure-attrs) - stroke-values (select-keys shape stroke-attrs)] - [:* - [:& measures-menu {:ids ids - :type type - :values measure-values}] - [:& fill-menu {:ids ids - :type type - :values (select-keys shape fill-attrs)}] - [:& stroke-menu {:ids ids - :type type - :values stroke-values}]])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/blur.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs similarity index 98% rename from frontend/src/app/main/ui/workspace/sidebar/options/blur.cljs rename to frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs index cd1463807..c2d675f9d 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/blur.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs @@ -7,7 +7,7 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns app.main.ui.workspace.sidebar.options.blur +(ns app.main.ui.workspace.sidebar.options.menus.blur (:require [rumext.alpha :as mf] [app.common.data :as d] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/component.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs similarity index 98% rename from frontend/src/app/main/ui/workspace/sidebar/options/component.cljs rename to frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs index b5f8455e0..743b44b4d 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/component.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs @@ -7,7 +7,7 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns app.main.ui.workspace.sidebar.options.component +(ns app.main.ui.workspace.sidebar.options.menus.component (:require [rumext.alpha :as mf] [app.common.pages :as cp] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/exports.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.cljs similarity index 99% rename from frontend/src/app/main/ui/workspace/sidebar/options/exports.cljs rename to frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.cljs index ef5c16f3f..0935c7038 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/exports.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.cljs @@ -7,7 +7,7 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns app.main.ui.workspace.sidebar.options.exports +(ns app.main.ui.workspace.sidebar.options.menus.exports (:require [cuerdas.core :as str] [beicon.core :as rx] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/fill.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs similarity index 98% rename from frontend/src/app/main/ui/workspace/sidebar/options/fill.cljs rename to frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs index f9a1c73a5..3a5491aa2 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/fill.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs @@ -7,7 +7,7 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns app.main.ui.workspace.sidebar.options.fill +(ns app.main.ui.workspace.sidebar.options.menus.fill (:require [app.common.pages :as cp] [app.main.data.colors :as dc] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/frame_grid.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/frame_grid.cljs similarity index 99% rename from frontend/src/app/main/ui/workspace/sidebar/options/frame_grid.cljs rename to frontend/src/app/main/ui/workspace/sidebar/options/menus/frame_grid.cljs index ac2a76463..dd6442da0 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/frame_grid.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/frame_grid.cljs @@ -7,7 +7,7 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns app.main.ui.workspace.sidebar.options.frame-grid +(ns app.main.ui.workspace.sidebar.options.menus.frame-grid (:require [rumext.alpha :as mf] [okulary.core :as l] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/interactions.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs similarity index 98% rename from frontend/src/app/main/ui/workspace/sidebar/options/interactions.cljs rename to frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs index 98f14837c..1b8033a8d 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/interactions.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs @@ -7,7 +7,7 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns app.main.ui.workspace.sidebar.options.interactions +(ns app.main.ui.workspace.sidebar.options.menus.interactions (:require [rumext.alpha :as mf] [app.common.data :as d] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layer.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layer.cljs new file mode 100644 index 000000000..90d9f62e8 --- /dev/null +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layer.cljs @@ -0,0 +1,141 @@ +;; 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/. +;; +;; This Source Code Form is "Incompatible With Secondary Licenses", as +;; defined by the Mozilla Public License, v. 2.0. +;; +;; Copyright (c) 2020-2021 UXBOX Labs SL + +(ns app.main.ui.workspace.sidebar.options.menus.layer + (:require + [app.common.data :as d] + [app.common.math :as mth] + [app.main.data.workspace.common :as dwc] + [app.main.store :as st] + [app.main.ui.components.numeric-input :refer [numeric-input]] + [app.main.ui.icons :as i] + [app.util.dom :as dom] + [app.util.i18n :as i18n :refer [tr]] + [rumext.alpha :as mf])) + +(def layer-attrs [:opacity :blend-mode :blocked :hidden]) + +(defn opacity->string [opacity] + (if (= opacity :multiple) + "" + (str (-> opacity + (d/coalesce 1) + (* 100) + (mth/round))))) + +(defn select-all [event] + (dom/select-text! (dom/get-target event))) + +(mf/defc layer-menu [{:keys [ids type values]}] + (let [change! + (mf/use-callback + (mf/deps ids) + (fn [prop value] + (st/emit! (dwc/update-shapes ids #(assoc % prop value))))) + + handle-change-blend-mode + (mf/use-callback + (mf/deps change!) + (fn [event] + (let [value (-> (dom/get-target-val event) (keyword))] + (change! :blend-mode value)))) + + handle-opacity-change + (mf/use-callback + (mf/deps change!) + (fn [value] + (let [value (-> value (/ 100))] + (change! :opacity value)))) + + handle-set-hidden + (mf/use-callback + (mf/deps change!) + (fn [event] + (change! :hidden true))) + + handle-set-visible + (mf/use-callback + (mf/deps change!) + (fn [event] + (change! :hidden false))) + + handle-set-blocked + (mf/use-callback + (mf/deps change!) + (fn [event] + (change! :blocked true))) + + handle-set-unblocked + (mf/use-callback + (mf/deps change!) + (fn [event] + (change! :blocked false)))] + + [:div.element-set + [:div.element-set-title + [:span + (case type + :multiple (tr "workspace.options.layer-options.title.multiple") + :group (tr "workspace.options.layer-options.title.group") + (tr "workspace.options.layer-options.title"))]] + + [:div.element-set-content + [:div.row-flex + [:select.input-select {:on-change handle-change-blend-mode + :value (d/name (:blend-mode values) "normal")} + + (when (= :multiple (:blend-mode values)) + [:option {:value "multiple"} "--"]) + + [:option {:value "normal"} (tr "workspace.options.layer-options.blend-mode.normal")] + + [:option {:value "darken"} (tr "workspace.options.layer-options.blend-mode.darken")] + [:option {:value "multiply"} (tr "workspace.options.layer-options.blend-mode.multiply")] + [:option {:value "color-burn"} (tr "workspace.options.layer-options.blend-mode.color-burn")] + + [:option {:value "lighten"} (tr "workspace.options.layer-options.blend-mode.lighten")] + [:option {:value "screen"} (tr "workspace.options.layer-options.blend-mode.screen")] + [:option {:value "color-dodge"} (tr "workspace.options.layer-options.blend-mode.color-dodge")] + + [:option {:value "overlay"} (tr "workspace.options.layer-options.blend-mode.overlay")] + [:option {:value "soft-light"} (tr "workspace.options.layer-options.blend-mode.soft-light")] + [:option {:value "hard-light"} (tr "workspace.options.layer-options.blend-mode.hard-light")] + + [:option {:value "difference"} (tr "workspace.options.layer-options.blend-mode.difference")] + [:option {:value "exclusion"} (tr "workspace.options.layer-options.blend-mode.exclusion")] + + [:option {:value "hue"} (tr "workspace.options.layer-options.blend-mode.hue")] + [:option {:value "saturation"} (tr "workspace.options.layer-options.blend-mode.saturation")] + [:option {:value "color"} (tr "workspace.options.layer-options.blend-mode.color")] + [:option {:value "luminosity"} (tr "workspace.options.layer-options.blend-mode.luminosity")]] + + [:div.input-element + {:class "percentail"} + [:> numeric-input {:value (-> values :opacity opacity->string) + :placeholder (tr "settings.multiple") + :on-click select-all + :on-change handle-opacity-change + :min 0 + :max 100}]] + + + [:div.element-set-actions.layer-actions + (cond + (or (= :multiple (:hidden values)) (not (:hidden values))) + [:div.element-set-actions-button {:on-click handle-set-hidden} i/eye] + + :else + [:div.element-set-actions-button {:on-click handle-set-visible} i/eye-closed]) + + (cond + (or (= :multiple (:blocked values)) (not (:blocked values))) + [:div.element-set-actions-button {:on-click handle-set-blocked} i/lock-open] + + :else + [:div.element-set-actions-button {:on-click handle-set-unblocked} i/lock])]]]])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/measures.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs similarity index 99% rename from frontend/src/app/main/ui/workspace/sidebar/options/measures.cljs rename to frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs index ec870bd6d..c50843af1 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/measures.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs @@ -7,7 +7,7 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns app.main.ui.workspace.sidebar.options.measures +(ns app.main.ui.workspace.sidebar.options.menus.measures (:require [rumext.alpha :as mf] [app.main.ui.icons :as i] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shadow.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/shadow.cljs similarity index 99% rename from frontend/src/app/main/ui/workspace/sidebar/options/shadow.cljs rename to frontend/src/app/main/ui/workspace/sidebar/options/menus/shadow.cljs index c6e4a4d38..5775cbd13 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shadow.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/shadow.cljs @@ -7,7 +7,7 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns app.main.ui.workspace.sidebar.options.shadow +(ns app.main.ui.workspace.sidebar.options.menus.shadow (:require [rumext.alpha :as mf] [app.common.data :as d] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/stroke.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs similarity index 99% rename from frontend/src/app/main/ui/workspace/sidebar/options/stroke.cljs rename to frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs index 8b1c9124f..f8461f4d5 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/stroke.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs @@ -7,7 +7,7 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns app.main.ui.workspace.sidebar.options.stroke +(ns app.main.ui.workspace.sidebar.options.menus.stroke (:require [cuerdas.core :as str] [rumext.alpha :as mf] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/svg_attrs.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs similarity index 98% rename from frontend/src/app/main/ui/workspace/sidebar/options/svg_attrs.cljs rename to frontend/src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs index c7dbdec88..71da8a7d5 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/svg_attrs.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs @@ -7,7 +7,7 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns app.main.ui.workspace.sidebar.options.svg-attrs +(ns app.main.ui.workspace.sidebar.options.menus.svg-attrs (:require [cuerdas.core :as str] [app.common.data :as d] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/text.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs similarity index 68% rename from frontend/src/app/main/ui/workspace/sidebar/options/text.cljs rename to frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs index 3cdb576a0..aaaddf629 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/text.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs @@ -7,31 +7,24 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns app.main.ui.workspace.sidebar.options.text +(ns app.main.ui.workspace.sidebar.options.menus.text (:require - [rumext.alpha :as mf] - [cuerdas.core :as str] - [okulary.core :as l] - [app.main.ui.context :as ctx] - [app.main.ui.icons :as i] [app.common.data :as d] [app.common.uuid :as uuid] - [app.main.data.workspace :as dw] [app.main.data.workspace.common :as dwc] - [app.main.data.workspace.texts :as dwt] [app.main.data.workspace.libraries :as dwl] - [app.main.store :as st] - [app.main.refs :as refs] - [app.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]] - [app.main.ui.workspace.sidebar.options.fill :refer [fill-menu]] - [app.main.ui.workspace.sidebar.options.shadow :refer [shadow-menu]] - [app.main.ui.workspace.sidebar.options.typography :refer [typography-entry typography-options]] - [app.main.ui.workspace.sidebar.options.blur :refer [blur-menu]] - [app.util.dom :as dom] + [app.main.data.workspace.texts :as dwt] [app.main.fonts :as fonts] - [app.util.i18n :as i18n :refer [tr t]] + [app.main.refs :as refs] + [app.main.store :as st] + [app.main.ui.context :as ctx] + [app.main.ui.icons :as i] + [app.main.ui.workspace.sidebar.options.menus.typography :refer [typography-entry typography-options]] + [app.util.dom :as dom] + [app.util.i18n :as i18n :refer [tr]] [app.util.text :as ut] - ["slate" :refer [Transforms]])) + [cuerdas.core :as str] + [rumext.alpha :as mf])) (def text-typography-attrs [:typography-ref-id :typography-ref-file]) (def text-fill-attrs [:fill-color :fill-opacity :fill-color-ref-id :fill-color-ref-file :fill-color-gradient :fill :opacity ]) @@ -56,7 +49,7 @@ (def attrs (d/concat #{} shape-attrs root-attrs paragraph-attrs text-attrs)) (mf/defc text-align-options - [{:keys [editor ids values locale on-change] :as props}] + [{:keys [editor ids values on-change] :as props}] (let [{:keys [text-align]} values text-align (or text-align "left") @@ -68,29 +61,29 @@ ;; --- Align [:div.align-icons [:span.tooltip.tooltip-bottom - {:alt (t locale "workspace.options.text-options.align-left") + {:alt (tr "workspace.options.text-options.align-left") :class (dom/classnames :current (= "left" text-align)) :on-click #(handle-change % "left")} i/text-align-left] [:span.tooltip.tooltip-bottom - {:alt (t locale "workspace.options.text-options.align-center") + {:alt (tr "workspace.options.text-options.align-center") :class (dom/classnames :current (= "center" text-align)) :on-click #(handle-change % "center")} i/text-align-center] [:span.tooltip.tooltip-bottom - {:alt (t locale "workspace.options.text-options.align-right") + {:alt (tr "workspace.options.text-options.align-right") :class (dom/classnames :current (= "right" text-align)) :on-click #(handle-change % "right")} i/text-align-right] [:span.tooltip.tooltip-bottom - {:alt (t locale "workspace.options.text-options.align-justify") + {:alt (tr "workspace.options.text-options.align-justify") :class (dom/classnames :current (= "justify" text-align)) :on-click #(handle-change % "justify")} i/text-align-justify]])) (mf/defc vertical-align - [{:keys [shapes editor ids values locale on-change] :as props}] + [{:keys [shapes editor ids values on-change] :as props}] (let [{:keys [vertical-align]} values vertical-align (or vertical-align "top") handle-change @@ -99,23 +92,23 @@ [:div.align-icons [:span.tooltip.tooltip-bottom - {:alt (t locale "workspace.options.text-options.align-top") + {:alt (tr "workspace.options.text-options.align-top") :class (dom/classnames :current (= "top" vertical-align)) :on-click #(handle-change % "top")} i/align-top] [:span.tooltip.tooltip-bottom - {:alt (t locale "workspace.options.text-options.align-middle") + {:alt (tr "workspace.options.text-options.align-middle") :class (dom/classnames :current (= "center" vertical-align)) :on-click #(handle-change % "center")} i/align-middle] [:span.tooltip.tooltip-bottom - {:alt (t locale "workspace.options.text-options.align-bottom") + {:alt (tr "workspace.options.text-options.align-bottom") :class (dom/classnames :current (= "bottom" vertical-align)) :on-click #(handle-change % "bottom")} i/align-bottom]])) (mf/defc grow-options - [{:keys [editor ids values locale on-change] :as props}] + [{:keys [editor ids values on-change] :as props}] (let [to-single-value (fn [coll] (if (> (count coll) 1) nil (first coll))) grow-type (->> values :grow-type) handle-change-grow @@ -124,23 +117,23 @@ [:div.align-icons [:span.tooltip.tooltip-bottom - {:alt (t locale "workspace.options.text-options.grow-fixed") + {:alt (tr "workspace.options.text-options.grow-fixed") :class (dom/classnames :current (= :fixed grow-type)) :on-click #(handle-change-grow % :fixed)} i/auto-fix] [:span.tooltip.tooltip-bottom - {:alt (t locale "workspace.options.text-options.grow-auto-width") + {:alt (tr "workspace.options.text-options.grow-auto-width") :class (dom/classnames :current (= :auto-width grow-type)) :on-click #(handle-change-grow % :auto-width)} i/auto-width] [:span.tooltip.tooltip-bottom - {:alt (t locale "workspace.options.text-options.grow-auto-height") + {:alt (tr "workspace.options.text-options.grow-auto-height") :class (dom/classnames :current (= :auto-height grow-type)) :on-click #(handle-change-grow % :auto-height)} i/auto-height]])) (mf/defc text-decoration-options - [{:keys [editor ids values locale on-change] :as props}] + [{:keys [editor ids values on-change] :as props}] (let [{:keys [text-decoration]} values text-decoration (or text-decoration "none") @@ -150,19 +143,19 @@ (on-change {:text-decoration type}))] [:div.align-icons [:span.tooltip.tooltip-bottom - {:alt (t locale "workspace.options.text-options.none") + {:alt (tr "workspace.options.text-options.none") :class (dom/classnames :current (= "none" text-decoration)) :on-click #(handle-change % "none")} i/minus] [:span.tooltip.tooltip-bottom - {:alt (t locale "workspace.options.text-options.underline") + {:alt (tr "workspace.options.text-options.underline") :class (dom/classnames :current (= "underline" text-decoration)) :on-click #(handle-change % "underline")} i/underline] [:span.tooltip.tooltip-bottom - {:alt (t locale "workspace.options.text-options.strikethrough") + {:alt (tr "workspace.options.text-options.strikethrough") :class (dom/classnames :current (= "line-through" text-decoration)) :on-click #(handle-change % "line-through")} i/strikethrough]])) @@ -176,14 +169,13 @@ {::mf/wrap [mf/memo]} [{:keys [ids type editor values] :as props}] - (let [locale (mf/deref i18n/locale) - current-file-id (mf/use-ctx ctx/current-file-id) + (let [current-file-id (mf/use-ctx ctx/current-file-id) typographies (mf/deref refs/workspace-file-typography) shared-libs (mf/deref refs/workspace-libraries) label (case type - :multiple (t locale "workspace.options.text-options.title-selection") - :group (t locale "workspace.options.text-options.title-group") - (t locale "workspace.options.text-options.title")) + :multiple (tr "workspace.options.text-options.title-selection") + :group (tr "workspace.options.text-options.title-group") + (tr "workspace.options.text-options.title")) emit-update! (fn [id attrs] @@ -242,8 +234,7 @@ :ids ids :values values :on-change (fn [attrs] - (run! #(emit-update! % attrs) ids)) - :locale locale}] + (run! #(emit-update! % attrs) ids))}] [:div.element-set [:div.element-set-title @@ -261,9 +252,9 @@ (= (:typography-ref-id values) :multiple) [:div.multiple-typography - [:div.multiple-typography-text (t locale "workspace.libraries.text.multiple-typography")] + [:div.multiple-typography-text (tr "workspace.libraries.text.multiple-typography")] [:div.multiple-typography-button {:on-click handle-detach-typography - :title (t locale "workspace.libraries.text.multiple-typography-tooltip")} i/unchain]] + :title (tr "workspace.libraries.text.multiple-typography-tooltip")} i/unchain]] :else [:> typography-options opts]) @@ -276,58 +267,5 @@ [:div.row-flex [:> grow-options opts] - [:> text-decoration-options opts]] + [:> text-decoration-options opts]]]])) - ]])) - -(mf/defc options - [{:keys [shape] :as props}] - (let [ids [(:id shape)] - type (:type shape) - - editors (mf/deref refs/editors) - editor (get editors (:id shape)) - - measure-values (select-keys shape measure-attrs) - - fill-values (dwt/current-text-values - {:editor editor - :shape shape - :attrs text-fill-attrs}) - - fill-values (d/update-in-when fill-values [:fill-color-gradient :type] keyword) - - fill-values (cond-> fill-values - ;; Keep for backwards compatibility - (:fill fill-values) (assoc :fill-color (:fill fill-values)) - (:opacity fill-values) (assoc :fill-opacity (:fill fill-values))) - - - text-values (merge - (select-keys shape [:grow-type]) - (dwt/current-root-values - {:editor editor :shape shape - :attrs root-attrs}) - (dwt/current-text-values - {:editor editor :shape shape - :attrs paragraph-attrs}) - (dwt/current-text-values - {:editor editor :shape shape - :attrs text-attrs}))] - - [:* - [:& measures-menu {:ids ids - :type type - :values measure-values}] - [:& fill-menu {:ids ids - :type type - :values fill-values - :editor editor}] - [:& shadow-menu {:ids ids - :values (select-keys shape [:shadow])}] - [:& blur-menu {:ids ids - :values (select-keys shape [:blur])}] - [:& text-menu {:ids ids - :type type - :values text-values - :editor editor}]])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/typography.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.cljs similarity index 99% rename from frontend/src/app/main/ui/workspace/sidebar/options/typography.cljs rename to frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.cljs index 6f4632aac..42daf3820 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/typography.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.cljs @@ -7,7 +7,7 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns app.main.ui.workspace.sidebar.options.typography +(ns app.main.ui.workspace.sidebar.options.menus.typography (:require [rumext.alpha :as mf] [cuerdas.core :as str] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/circle.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/circle.cljs similarity index 59% rename from frontend/src/app/main/ui/workspace/sidebar/options/circle.cljs rename to frontend/src/app/main/ui/workspace/sidebar/options/shapes/circle.cljs index d39e86a0b..59fbfcdbc 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/circle.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/circle.cljs @@ -7,27 +7,32 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns app.main.ui.workspace.sidebar.options.circle +(ns app.main.ui.workspace.sidebar.options.shapes.circle (:require [rumext.alpha :as mf] - [app.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]] - [app.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]] - [app.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]] - [app.main.ui.workspace.sidebar.options.shadow :refer [shadow-menu]] - [app.main.ui.workspace.sidebar.options.blur :refer [blur-menu]] - [app.main.ui.workspace.sidebar.options.svg-attrs :refer [svg-attrs-menu]])) + [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]] + [app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]] + [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] + [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]] + [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] + [app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]] + [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]])) (mf/defc options [{:keys [shape] :as props}] (let [ids [(:id shape)] type (:type shape) measure-values (select-keys shape measure-attrs) - stroke-values (select-keys shape stroke-attrs)] + stroke-values (select-keys shape stroke-attrs) + layer-values (select-keys shape layer-attrs)] [:* [:& measures-menu {:ids ids :type type :values measure-values :options #{:size :position :rotation}}] + [:& layer-menu {:ids ids + :type type + :values layer-values}] [:& fill-menu {:ids ids :type type :values (select-keys shape fill-attrs)}] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/frame.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs similarity index 92% rename from frontend/src/app/main/ui/workspace/sidebar/options/frame.cljs rename to frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs index 5c7440920..1845cf979 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/frame.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs @@ -8,7 +8,7 @@ ;; Copyright (c) 2015-2020 Andrey Antukh ;; Copyright (c) 2015-2020 Juan de la Cruz -(ns app.main.ui.workspace.sidebar.options.frame +(ns app.main.ui.workspace.sidebar.options.shapes.frame (:require [rumext.alpha :as mf] [app.common.data :as d] @@ -21,11 +21,12 @@ [app.main.ui.icons :as i] [app.main.ui.components.dropdown :refer [dropdown]] [app.main.ui.components.numeric-input :refer [numeric-input]] - [app.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]] - [app.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]] - [app.main.ui.workspace.sidebar.options.frame-grid :refer [frame-grid]] - [app.main.ui.workspace.sidebar.options.shadow :refer [shadow-menu]] - [app.main.ui.workspace.sidebar.options.blur :refer [blur-menu]])) + [app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]] + [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] + [app.main.ui.workspace.sidebar.options.menus.frame-grid :refer [frame-grid]] + [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]] + [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] + [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]])) (declare +size-presets+) @@ -299,9 +300,13 @@ [{:keys [shape] :as props}] (let [ids [(:id shape)] type (:type shape) - stroke-values (select-keys shape stroke-attrs)] + stroke-values (select-keys shape stroke-attrs) + layer-values (select-keys shape layer-attrs)] [:* [:& measures-menu {:shape shape}] + [:& layer-menu {:ids ids + :type type + :values layer-values}] [:& fill-menu {:ids ids :type type :values (select-keys shape fill-attrs)}] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/group.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/group.cljs similarity index 69% rename from frontend/src/app/main/ui/workspace/sidebar/options/group.cljs rename to frontend/src/app/main/ui/workspace/sidebar/options/shapes/group.cljs index 82dabbf03..f6e16a568 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/group.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/group.cljs @@ -8,19 +8,20 @@ ;; Copyright (c) 2015-2020 Andrey Antukh ;; Copyright (c) 2015-2020 Juan de la Cruz -(ns app.main.ui.workspace.sidebar.options.group +(ns app.main.ui.workspace.sidebar.options.shapes.group (:require [rumext.alpha :as mf] [app.common.data :as d] - [app.main.ui.workspace.sidebar.options.multiple :refer [get-attrs]] - [app.main.ui.workspace.sidebar.options.measures :refer [measures-menu]] - [app.main.ui.workspace.sidebar.options.component :refer [component-attrs component-menu]] - [app.main.ui.workspace.sidebar.options.fill :refer [fill-menu]] - [app.main.ui.workspace.sidebar.options.blur :refer [blur-menu]] - [app.main.ui.workspace.sidebar.options.shadow :refer [shadow-menu]] - [app.main.ui.workspace.sidebar.options.stroke :refer [stroke-menu]] - [app.main.ui.workspace.sidebar.options.text :as ot] - [app.main.ui.workspace.sidebar.options.svg-attrs :refer [svg-attrs-menu]])) + [app.main.ui.workspace.sidebar.options.shapes.multiple :refer [get-attrs]] + [app.main.ui.workspace.sidebar.options.menus.measures :refer [measures-menu]] + [app.main.ui.workspace.sidebar.options.menus.component :refer [component-attrs component-menu]] + [app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-menu]] + [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] + [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]] + [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-menu]] + [app.main.ui.workspace.sidebar.options.menus.text :as ot] + [app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]] + [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]])) (mf/defc options {::mf/wrap [mf/memo] @@ -32,6 +33,7 @@ type :group [measure-ids measure-values] (get-attrs [shape] objects :measure) + [layer-ids layer-values] (get-attrs [shape] objects :layer) [fill-ids fill-values] (get-attrs [shape] objects :fill) [shadow-ids shadow-values] (get-attrs [shape] objects :shadow) [blur-ids blur-values] (get-attrs [shape] objects :blur) @@ -42,6 +44,7 @@ [:div.options [:& measures-menu {:type type :ids measure-ids :values measure-values}] + [:& layer-menu {:type type :ids layer-ids :values layer-values}] [:& component-menu {:ids comp-ids :values comp-values}] (when-not (empty? fill-ids) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/image.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/image.cljs similarity index 57% rename from frontend/src/app/main/ui/workspace/sidebar/options/image.cljs rename to frontend/src/app/main/ui/workspace/sidebar/options/shapes/image.cljs index d8733c7a9..32e2fda46 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/image.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/image.cljs @@ -7,22 +7,27 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns app.main.ui.workspace.sidebar.options.image +(ns app.main.ui.workspace.sidebar.options.shapes.image (:require [rumext.alpha :as mf] - [app.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]] - [app.main.ui.workspace.sidebar.options.shadow :refer [shadow-menu]] - [app.main.ui.workspace.sidebar.options.blur :refer [blur-menu]])) + [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]] + [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]] + [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] + [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]])) (mf/defc options [{:keys [shape] :as props}] (let [ids [(:id shape)] type (:type shape) - measure-values (select-keys shape measure-attrs)] + measure-values (select-keys shape measure-attrs) + layer-values (select-keys shape layer-attrs)] [:* [:& measures-menu {:ids ids :type type :values measure-values}] + [:& layer-menu {:ids ids + :type type + :values layer-values}] [:& shadow-menu {:ids ids :values (select-keys shape [:shadow])}] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/multiple.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs similarity index 85% rename from frontend/src/app/main/ui/workspace/sidebar/options/multiple.cljs rename to frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs index 895131571..0e4a47ab2 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/multiple.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs @@ -7,24 +7,26 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns app.main.ui.workspace.sidebar.options.multiple +(ns app.main.ui.workspace.sidebar.options.shapes.multiple (:require [app.common.data :as d] [rumext.alpha :as mf] [app.common.attrs :as attrs] [app.util.text :as ut] - [app.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]] - [app.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]] - [app.main.ui.workspace.sidebar.options.shadow :refer [shadow-attrs shadow-menu]] - [app.main.ui.workspace.sidebar.options.blur :refer [blur-attrs blur-menu]] - [app.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]] - [app.main.ui.workspace.sidebar.options.text :as ot])) + [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]] + [app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]] + [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-attrs shadow-menu]] + [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-attrs blur-menu]] + [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] + [app.main.ui.workspace.sidebar.options.menus.text :as ot] + [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]])) ;; We define a map that goes from type to ;; attribute and how to handle them (def type->props {:frame {:measure :shape + :layer :shape :fill :shape :shadow :children :blur :children @@ -33,6 +35,7 @@ :group {:measure :shape + :layer :shape :fill :children :shadow :shape :blur :shape @@ -41,6 +44,7 @@ :path {:measure :shape + :layer :shape :fill :shape :shadow :shape :blur :shape @@ -49,6 +53,7 @@ :text {:measure :shape + :layer :shape :fill :text :shadow :shape :blur :shape @@ -57,6 +62,7 @@ :image {:measure :shape + :layer :shape :fill :ignore :shadow :shape :blur :shape @@ -65,6 +71,7 @@ :rect {:measure :shape + :layer :shape :fill :shape :shadow :shape :blur :shape @@ -73,6 +80,7 @@ :circle {:measure :shape + :layer :shape :fill :shape :shadow :shape :blur :shape @@ -81,6 +89,7 @@ :svg-raw {:measure :shape + :layer :shape :fill :shape :shadow :shape :blur :shape @@ -89,6 +98,7 @@ (def props->attrs {:measure measure-attrs + :layer layer-attrs :fill fill-attrs :shadow shadow-attrs :blur blur-attrs @@ -169,6 +179,7 @@ type :multiple [measure-ids measure-values] (get-attrs shapes objects :measure) + [layer-ids layer-values] (get-attrs shapes objects :layer) [fill-ids fill-values] (get-attrs shapes objects :fill) [shadow-ids shadow-values] (get-attrs shapes objects :shadow) [blur-ids blur-values] (get-attrs shapes objects :blur) @@ -179,6 +190,9 @@ (when-not (empty? measure-ids) [:& measures-menu {:type type :ids measure-ids :values measure-values}]) + (when-not (empty? layer-ids) + [:& layer-menu {:type type :ids layer-ids :values layer-values}]) + (when-not (empty? fill-ids) [:& fill-menu {:type type :ids fill-ids :values fill-values}]) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/path.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/path.cljs similarity index 58% rename from frontend/src/app/main/ui/workspace/sidebar/options/path.cljs rename to frontend/src/app/main/ui/workspace/sidebar/options/shapes/path.cljs index f224df3d7..0faebc12d 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/path.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/path.cljs @@ -7,27 +7,32 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns app.main.ui.workspace.sidebar.options.path +(ns app.main.ui.workspace.sidebar.options.shapes.path (:require [rumext.alpha :as mf] [app.common.data :as d] - [app.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]] - [app.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]] - [app.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]] - [app.main.ui.workspace.sidebar.options.shadow :refer [shadow-menu]] - [app.main.ui.workspace.sidebar.options.blur :refer [blur-menu]] - [app.main.ui.workspace.sidebar.options.svg-attrs :refer [svg-attrs-menu]])) + [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]] + [app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]] + [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] + [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]] + [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] + [app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]] + [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]])) (mf/defc options [{:keys [shape] :as props}] (let [ids [(:id shape)] type (:type shape) measure-values (select-keys shape measure-attrs) - stroke-values (select-keys shape stroke-attrs)] + stroke-values (select-keys shape stroke-attrs) + layer-values (select-keys shape layer-attrs)] [:* [:& measures-menu {:ids ids :type type :values measure-values}] + [:& layer-menu {:ids ids + :type type + :values layer-values}] [:& fill-menu {:ids ids :type type :values (select-keys shape fill-attrs)}] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/rect.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/rect.cljs similarity index 62% rename from frontend/src/app/main/ui/workspace/sidebar/options/rect.cljs rename to frontend/src/app/main/ui/workspace/sidebar/options/shapes/rect.cljs index d3f1464bd..c64656c31 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/rect.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/rect.cljs @@ -7,15 +7,16 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns app.main.ui.workspace.sidebar.options.rect +(ns app.main.ui.workspace.sidebar.options.shapes.rect (:require [rumext.alpha :as mf] - [app.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]] - [app.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]] - [app.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]] - [app.main.ui.workspace.sidebar.options.shadow :refer [shadow-menu]] - [app.main.ui.workspace.sidebar.options.blur :refer [blur-menu]] - [app.main.ui.workspace.sidebar.options.svg-attrs :refer [svg-attrs-menu]])) + [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]] + [app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]] + [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] + [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]] + [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] + [app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]] + [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]])) (mf/defc options {::mf/wrap [mf/memo]} @@ -23,6 +24,7 @@ (let [ids [(:id shape)] type (:type shape) measure-values (select-keys shape measure-attrs) + layer-values (select-keys shape layer-attrs) fill-values (select-keys shape fill-attrs) stroke-values (select-keys shape stroke-attrs)] [:* @@ -30,6 +32,10 @@ :type type :values measure-values}] + [:& layer-menu {:ids ids + :type type + :values layer-values}] + [:& fill-menu {:ids ids :type type :values fill-values}] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/svg_raw.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/svg_raw.cljs similarity index 87% rename from frontend/src/app/main/ui/workspace/sidebar/options/svg_raw.cljs rename to frontend/src/app/main/ui/workspace/sidebar/options/shapes/svg_raw.cljs index a6ee9d346..88b6577f1 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/svg_raw.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/svg_raw.cljs @@ -7,18 +7,18 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns app.main.ui.workspace.sidebar.options.svg-raw +(ns app.main.ui.workspace.sidebar.options.shapes.svg-raw (:require [rumext.alpha :as mf] [cuerdas.core :as str] [app.util.data :as d] [app.util.color :as uc] - [app.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]] - [app.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]] - [app.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]] - [app.main.ui.workspace.sidebar.options.shadow :refer [shadow-menu]] - [app.main.ui.workspace.sidebar.options.blur :refer [blur-menu]] - [app.main.ui.workspace.sidebar.options.svg-attrs :refer [svg-attrs-menu]])) + [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]] + [app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]] + [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] + [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]] + [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] + [app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]])) ;; This is a list of svg tags that can be grouped in shape-container ;; this allows them to have gradients, shadows and masks diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs new file mode 100644 index 000000000..7ff4071ad --- /dev/null +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs @@ -0,0 +1,72 @@ +;; 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/. +;; +;; 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 app.main.ui.workspace.sidebar.options.shapes.text + (:require + [app.common.data :as d] + [app.main.data.workspace.texts :as dwt] + [app.main.refs :as refs] + [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] + [app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-menu]] + [app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]] + [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]] + [app.main.ui.workspace.sidebar.options.menus.text :refer [text-menu text-fill-attrs root-attrs paragraph-attrs text-attrs]] + [rumext.alpha :as mf])) + +(mf/defc options + [{:keys [shape] :as props}] + (let [ids [(:id shape)] + type (:type shape) + + editors (mf/deref refs/editors) + editor (get editors (:id shape)) + + measure-values (select-keys shape measure-attrs) + + fill-values (dwt/current-text-values + {:editor editor + :shape shape + :attrs text-fill-attrs}) + + fill-values (d/update-in-when fill-values [:fill-color-gradient :type] keyword) + + fill-values (cond-> fill-values + ;; Keep for backwards compatibility + (:fill fill-values) (assoc :fill-color (:fill fill-values)) + (:opacity fill-values) (assoc :fill-opacity (:fill fill-values))) + + + text-values (merge + (select-keys shape [:grow-type]) + (dwt/current-root-values + {:editor editor :shape shape + :attrs root-attrs}) + (dwt/current-text-values + {:editor editor :shape shape + :attrs paragraph-attrs}) + (dwt/current-text-values + {:editor editor :shape shape + :attrs text-attrs}))] + + [:* + [:& measures-menu {:ids ids + :type type + :values measure-values}] + [:& fill-menu {:ids ids + :type type + :values fill-values + :editor editor}] + [:& shadow-menu {:ids ids + :values (select-keys shape [:shadow])}] + [:& blur-menu {:ids ids + :values (select-keys shape [:blur])}] + [:& text-menu {:ids ids + :type type + :values text-values + :editor editor}]]))