mirror of
https://github.com/penpot/penpot.git
synced 2025-03-16 01:31:22 -05:00
Merge pull request #272 from uxbox/304/edit-multi-properties
🎉 Allow change fill color of multiple objects
This commit is contained in:
commit
a2abe6d882
22 changed files with 542 additions and 283 deletions
|
@ -168,24 +168,7 @@
|
|||
:proportion 1
|
||||
:proportion-lock false))
|
||||
|
||||
;; --- Resize (Dimentsions)
|
||||
|
||||
(defn resize-rect
|
||||
[shape attr value]
|
||||
(us/assert map? shape)
|
||||
(us/assert #{:width :height} attr)
|
||||
(us/assert number? value)
|
||||
|
||||
(let [{:keys [proportion proportion-lock]} shape]
|
||||
(if-not proportion-lock
|
||||
(assoc shape attr value)
|
||||
(if (= attr :width)
|
||||
(-> shape
|
||||
(assoc :width value)
|
||||
(assoc :height (/ value proportion)))
|
||||
(-> shape
|
||||
(assoc :height value)
|
||||
(assoc :width (* value proportion)))))))
|
||||
;; --- Resize (Dimensions)
|
||||
|
||||
(defn resize
|
||||
[shape width height]
|
||||
|
@ -199,6 +182,24 @@
|
|||
:x2 (+ (:x1 selrect) width)
|
||||
:y2 (+ (:y1 selrect) height))))))
|
||||
|
||||
(defn resize-rect
|
||||
[shape attr value]
|
||||
(us/assert map? shape)
|
||||
(us/assert #{:width :height} attr)
|
||||
(us/assert number? value)
|
||||
(let [{:keys [proportion proportion-lock]} shape
|
||||
size (select-keys shape [:width :height])
|
||||
new-size (if-not proportion-lock
|
||||
(assoc size attr value)
|
||||
(if (= attr :width)
|
||||
(-> size
|
||||
(assoc :width value)
|
||||
(assoc :height (/ value proportion)))
|
||||
(-> size
|
||||
(assoc :height value)
|
||||
(assoc :width (* value proportion)))))]
|
||||
(resize shape (:width new-size) (:height new-size))))
|
||||
|
||||
;; --- Setup (Initialize)
|
||||
|
||||
(declare setup-rect)
|
||||
|
|
|
@ -416,7 +416,7 @@
|
|||
}
|
||||
},
|
||||
"dashboard.sidebar.drafts" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/sidebar.cljs:128" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/sidebar.cljs:129" ],
|
||||
"translations" : {
|
||||
"en" : "Drafts",
|
||||
"fr" : "Brouillons",
|
||||
|
@ -424,7 +424,7 @@
|
|||
}
|
||||
},
|
||||
"dashboard.sidebar.libraries" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/sidebar.cljs:134" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/sidebar.cljs:135" ],
|
||||
"translations" : {
|
||||
"en" : "Libraries",
|
||||
"fr" : "Librairies",
|
||||
|
@ -432,7 +432,7 @@
|
|||
}
|
||||
},
|
||||
"dashboard.sidebar.recent" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/sidebar.cljs:121" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/sidebar.cljs:122" ],
|
||||
"translations" : {
|
||||
"en" : "Recent",
|
||||
"fr" : "Récent",
|
||||
|
@ -528,7 +528,7 @@
|
|||
}
|
||||
},
|
||||
"ds.search.placeholder" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/sidebar.cljs:187" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/sidebar.cljs:188" ],
|
||||
"translations" : {
|
||||
"en" : "Search...",
|
||||
"fr" : "Rechercher...",
|
||||
|
@ -584,7 +584,7 @@
|
|||
}
|
||||
},
|
||||
"errors.image-format-unsupported" : {
|
||||
"used-in" : [ "src/uxbox/main/data/users.cljs:177", "src/uxbox/main/data/workspace/persistence.cljs:365", "src/uxbox/main/data/images.cljs:376" ],
|
||||
"used-in" : [ "src/uxbox/main/data/images.cljs:376", "src/uxbox/main/data/workspace/persistence.cljs:365", "src/uxbox/main/data/users.cljs:177" ],
|
||||
"translations" : {
|
||||
"en" : "The image format is not supported (must be svg, jpg or png).",
|
||||
"fr" : "Le format d'image n'est pas supporté (doit être svg, jpg ou png).",
|
||||
|
@ -592,7 +592,7 @@
|
|||
}
|
||||
},
|
||||
"errors.image-too-large" : {
|
||||
"used-in" : [ "src/uxbox/main/data/users.cljs:175", "src/uxbox/main/data/workspace/persistence.cljs:363", "src/uxbox/main/data/images.cljs:374" ],
|
||||
"used-in" : [ "src/uxbox/main/data/images.cljs:374", "src/uxbox/main/data/workspace/persistence.cljs:363", "src/uxbox/main/data/users.cljs:175" ],
|
||||
"translations" : {
|
||||
"en" : "The image is too large to be inserted (must be under 5mb).",
|
||||
"fr" : "L'image est trop grande (doit être inférieure à 5 Mo).",
|
||||
|
@ -632,7 +632,7 @@
|
|||
}
|
||||
},
|
||||
"errors.unexpected-error" : {
|
||||
"used-in" : [ "src/uxbox/main/data/users.cljs:185", "src/uxbox/main/data/workspace/persistence.cljs:334", "src/uxbox/main/data/workspace/persistence.cljs:374", "src/uxbox/main/data/images.cljs:385", "src/uxbox/main/ui/settings/change_email.cljs:51", "src/uxbox/main/ui/auth/register.cljs:54" ],
|
||||
"used-in" : [ "src/uxbox/main/data/images.cljs:385", "src/uxbox/main/data/workspace/persistence.cljs:334", "src/uxbox/main/data/workspace/persistence.cljs:374", "src/uxbox/main/data/users.cljs:185", "src/uxbox/main/ui/auth/register.cljs:54", "src/uxbox/main/ui/settings/change_email.cljs:51" ],
|
||||
"translations" : {
|
||||
"en" : "An unexpected error occurred.",
|
||||
"fr" : "Une erreur inattendue c'est produite",
|
||||
|
@ -672,7 +672,7 @@
|
|||
}
|
||||
},
|
||||
"image.loading" : {
|
||||
"used-in" : [ "src/uxbox/main/data/users.cljs:191", "src/uxbox/main/data/workspace/persistence.cljs:341", "src/uxbox/main/data/workspace/persistence.cljs:382", "src/uxbox/main/data/images.cljs:393" ],
|
||||
"used-in" : [ "src/uxbox/main/data/images.cljs:393", "src/uxbox/main/data/workspace/persistence.cljs:341", "src/uxbox/main/data/workspace/persistence.cljs:382", "src/uxbox/main/data/users.cljs:191" ],
|
||||
"translations" : {
|
||||
"en" : "Loading image...",
|
||||
"fr" : "Chargement de l'image...",
|
||||
|
@ -839,6 +839,13 @@
|
|||
"es" : "Cambiar el idioma de la interfaz"
|
||||
}
|
||||
},
|
||||
"settings.multiple" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:132", "src/uxbox/main/ui/workspace/sidebar/options/rows/color_row.cljs:117", "src/uxbox/main/ui/workspace/sidebar/options/rows/color_row.cljs:126" ],
|
||||
"translations" : {
|
||||
"en" : "Multiple",
|
||||
"es" : "Múltiple"
|
||||
}
|
||||
},
|
||||
"settings.new-email-label" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/change_email.cljs:75" ],
|
||||
"translations" : {
|
||||
|
@ -1360,7 +1367,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.design" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options.cljs:107" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options.cljs:70" ],
|
||||
"translations" : {
|
||||
"en" : "Design",
|
||||
"fr" : "Conception",
|
||||
|
@ -1380,7 +1387,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.fill" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:383", "src/uxbox/main/ui/workspace/sidebar/options/fill.cljs:41" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/fill.cljs:40", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:382" ],
|
||||
"translations" : {
|
||||
"en" : "Fill",
|
||||
"fr" : "Remplissage",
|
||||
|
@ -1388,7 +1395,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.font-options" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:389" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:388" ],
|
||||
"translations" : {
|
||||
"en" : "Text",
|
||||
"fr" : "Texte",
|
||||
|
@ -1396,7 +1403,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.font-options.align-bottom" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:294" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:293" ],
|
||||
"translations" : {
|
||||
"en" : "Align bottom",
|
||||
"fr" : "Aligner en bas",
|
||||
|
@ -1428,7 +1435,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.font-options.align-middle" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:289" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:288" ],
|
||||
"translations" : {
|
||||
"en" : "Align middle",
|
||||
"fr" : "Aligner au milieu",
|
||||
|
@ -1444,7 +1451,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.font-options.align-top" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:284" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:283" ],
|
||||
"translations" : {
|
||||
"en" : "Align top",
|
||||
"fr" : "Aligner en haut",
|
||||
|
@ -1452,7 +1459,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.font-options.decoration" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:315" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:314" ],
|
||||
"translations" : {
|
||||
"en" : "Decoration",
|
||||
"fr" : "Décoration",
|
||||
|
@ -1460,7 +1467,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.font-options.letter-spacing" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:241" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:240" ],
|
||||
"translations" : {
|
||||
"en" : "Letter Spacing",
|
||||
"fr" : "Espacement de caractères",
|
||||
|
@ -1468,7 +1475,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.font-options.line-height" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:229" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:228" ],
|
||||
"translations" : {
|
||||
"en" : "Line height",
|
||||
"fr" : "Hauteur de ligne",
|
||||
|
@ -1476,7 +1483,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.font-options.lowercase" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:364" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:363" ],
|
||||
"translations" : {
|
||||
"en" : "Lowercase",
|
||||
"fr" : "Minuscule",
|
||||
|
@ -1484,7 +1491,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.font-options.none" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:318", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:354" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:317", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:353" ],
|
||||
"translations" : {
|
||||
"en" : "None",
|
||||
"fr" : "Aucune",
|
||||
|
@ -1492,7 +1499,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.font-options.strikethrough" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:330" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:329" ],
|
||||
"translations" : {
|
||||
"en" : "Strikethrough",
|
||||
"fr" : "Barré",
|
||||
|
@ -1500,7 +1507,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.font-options.text-case" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:351" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:350" ],
|
||||
"translations" : {
|
||||
"en" : "Case",
|
||||
"fr" : "Casse",
|
||||
|
@ -1508,7 +1515,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.font-options.titlecase" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:369" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:368" ],
|
||||
"translations" : {
|
||||
"en" : "Titlecase",
|
||||
"fr" : "Titre",
|
||||
|
@ -1516,7 +1523,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.font-options.underline" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:324" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:323" ],
|
||||
"translations" : {
|
||||
"en" : "Underline",
|
||||
"fr" : "Souligner",
|
||||
|
@ -1524,7 +1531,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.font-options.uppercase" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:359" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:358" ],
|
||||
"translations" : {
|
||||
"en" : "Uppercase",
|
||||
"fr" : "Majuscule",
|
||||
|
@ -1532,7 +1539,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.font-options.vertical-align" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:281" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:280" ],
|
||||
"translations" : {
|
||||
"en" : "Vertical align",
|
||||
"fr" : "Alignement vertical",
|
||||
|
@ -1707,6 +1714,20 @@
|
|||
"es" : "Rejilla & Estructuras"
|
||||
}
|
||||
},
|
||||
"workspace.options.group-fill" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/fill.cljs:39" ],
|
||||
"translations" : {
|
||||
"en" : "Group fill",
|
||||
"es" : "Relleno de grupo"
|
||||
}
|
||||
},
|
||||
"workspace.options.group-stroke" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:65" ],
|
||||
"translations" : {
|
||||
"en" : "Group stroke",
|
||||
"es" : "Borde de grupo"
|
||||
}
|
||||
},
|
||||
"workspace.options.navigate-to" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:59" ],
|
||||
"translations" : {
|
||||
|
@ -1724,7 +1745,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.position" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/frame.cljs:125", "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:112" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:112", "src/uxbox/main/ui/workspace/sidebar/options/frame.cljs:125" ],
|
||||
"translations" : {
|
||||
"en" : "Position",
|
||||
"fr" : "Position",
|
||||
|
@ -1732,7 +1753,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.prototype" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options.cljs:115" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options.cljs:80" ],
|
||||
"translations" : {
|
||||
"en" : "Prototype",
|
||||
"fr" : "Prototype",
|
||||
|
@ -1771,8 +1792,22 @@
|
|||
"es" : "Selecciona un tablero"
|
||||
}
|
||||
},
|
||||
"workspace.options.selection-fill" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/fill.cljs:38" ],
|
||||
"translations" : {
|
||||
"en" : "Selection fill",
|
||||
"es" : "Relleno de selección"
|
||||
}
|
||||
},
|
||||
"workspace.options.selection-stroke" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:64" ],
|
||||
"translations" : {
|
||||
"en" : "Selection stroke",
|
||||
"es" : "Borde de selección"
|
||||
}
|
||||
},
|
||||
"workspace.options.size" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/frame.cljs:98", "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:82" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:82", "src/uxbox/main/ui/workspace/sidebar/options/frame.cljs:98" ],
|
||||
"translations" : {
|
||||
"en" : "Size",
|
||||
"fr" : "Taille",
|
||||
|
@ -1788,7 +1823,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.stroke" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:90", "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:124" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:66" ],
|
||||
"translations" : {
|
||||
"en" : "Stroke",
|
||||
"fr" : "Bordure",
|
||||
|
@ -1796,7 +1831,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.stroke.center" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:110" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:139" ],
|
||||
"translations" : {
|
||||
"en" : "Center",
|
||||
"fr" : "Centre",
|
||||
|
@ -1804,7 +1839,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.stroke.dashed" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:118" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:149" ],
|
||||
"translations" : {
|
||||
"en" : "Dashed",
|
||||
"fr" : "Tiré",
|
||||
|
@ -1812,7 +1847,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.stroke.dotted" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:117" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:148" ],
|
||||
"translations" : {
|
||||
"en" : "Dotted",
|
||||
"fr" : "Pointillé",
|
||||
|
@ -1820,7 +1855,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.stroke.inner" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:111" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:140" ],
|
||||
"translations" : {
|
||||
"en" : "Inside",
|
||||
"fr" : "Intérieur",
|
||||
|
@ -1828,7 +1863,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.stroke.mixed" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:119" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:150" ],
|
||||
"translations" : {
|
||||
"en" : "Mixed",
|
||||
"fr" : "Mixte",
|
||||
|
@ -1836,7 +1871,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.stroke.outer" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:112" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:141" ],
|
||||
"translations" : {
|
||||
"en" : "Outside",
|
||||
"fr" : "Extérieur",
|
||||
|
@ -1844,7 +1879,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.stroke.solid" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:116" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:147" ],
|
||||
"translations" : {
|
||||
"en" : "Solid",
|
||||
"fr" : "Solide",
|
||||
|
|
|
@ -176,10 +176,13 @@
|
|||
&:invalid {
|
||||
border-color: $color-danger;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
::placeholder{
|
||||
color: $color-gray-10;
|
||||
}
|
||||
|
||||
.type {
|
||||
color: $color-gray-10;
|
||||
margin-right: $x-small;
|
||||
|
|
|
@ -238,13 +238,17 @@
|
|||
}
|
||||
|
||||
&.selected {
|
||||
|
||||
svg {
|
||||
fill: $color-primary;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
cursor: unset;
|
||||
svg {
|
||||
fill: $color-gray-40;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
|
@ -444,6 +448,10 @@
|
|||
border: 1px solid $color-gray-10;
|
||||
border-radius: $br-small;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: $color-gray-10;
|
||||
flex-shrink: 0;
|
||||
height: 20px;
|
||||
margin: 5px 4px 0 0;
|
||||
|
|
|
@ -924,29 +924,29 @@
|
|||
;; object from workspace sidebar options inputs.
|
||||
|
||||
(defn update-dimensions
|
||||
[id attr value]
|
||||
(us/verify ::us/uuid id)
|
||||
[ids attr value]
|
||||
(us/verify (s/coll-of ::us/uuid) ids)
|
||||
(us/verify #{:width :height} attr)
|
||||
(us/verify ::us/number value)
|
||||
(ptk/reify ::update-dimensions
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(rx/of (dwc/update-shapes [id] #(geom/resize-rect % attr value))))))
|
||||
(rx/of (dwc/update-shapes ids #(geom/resize-rect % attr value))))))
|
||||
|
||||
|
||||
;; --- Shape Proportions
|
||||
|
||||
(defn toggle-shape-proportion-lock
|
||||
[id]
|
||||
(ptk/reify ::toggle-shape-proportion-lock
|
||||
(defn set-shape-proportion-lock
|
||||
[id lock]
|
||||
(ptk/reify ::set-shape-proportion-lock
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [page-id (:current-page-id state)
|
||||
shape (get-in state [:workspace-data page-id :objects id])]
|
||||
(if (:proportion-lock shape)
|
||||
(assoc-in state [:workspace-data page-id :objects id :proportion-lock] false)
|
||||
(->> (geom/assign-proportions (assoc shape :proportion-lock true))
|
||||
(assoc-in state [:workspace-data page-id :objects id])))))))
|
||||
(if-not lock
|
||||
(assoc-in state [:workspace-data page-id :objects id :proportion-lock] lock))
|
||||
(->> (geom/assign-proportions (assoc shape :proportion-lock lock))
|
||||
(assoc-in state [:workspace-data page-id :objects id]))))))
|
||||
|
||||
;; --- Update Shape Position
|
||||
|
||||
|
|
|
@ -119,6 +119,14 @@
|
|||
(def selected-shapes
|
||||
(l/derived :selected workspace-local))
|
||||
|
||||
(def selected-objects
|
||||
(letfn [(selector [state]
|
||||
(let [selected (get-in state [:workspace-local :selected])
|
||||
page-id (get-in state [:workspace-page :id])
|
||||
objects (get-in state [:workspace-data page-id :objects])]
|
||||
(->> selected (mapv #(get objects %)))))]
|
||||
(l/derived selector st/state =)))
|
||||
|
||||
(def selected-shapes-with-children
|
||||
(letfn [(selector [state]
|
||||
(let [selected (get-in state [:workspace-local :selected])
|
||||
|
|
|
@ -26,11 +26,12 @@
|
|||
[uxbox.main.ui.workspace.sidebar.options.group :as group]
|
||||
[uxbox.main.ui.workspace.sidebar.options.icon :as icon]
|
||||
[uxbox.main.ui.workspace.sidebar.options.image :as image]
|
||||
[uxbox.main.ui.workspace.sidebar.options.interactions :refer [interactions-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.text :as text]
|
||||
[uxbox.main.ui.workspace.sidebar.options.page :as page]
|
||||
[uxbox.main.ui.workspace.sidebar.options.multiple :as multiple]
|
||||
[uxbox.main.ui.workspace.sidebar.options.interactions :refer [interactions-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.path :as path]
|
||||
[uxbox.main.ui.workspace.sidebar.options.rect :as rect]
|
||||
[uxbox.main.ui.workspace.sidebar.options.text :as text]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.util.http :as http]
|
||||
[uxbox.util.i18n :as i18n :refer [tr t]]
|
||||
|
@ -106,7 +107,7 @@
|
|||
|
||||
(mf/defc options-content
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [section selected shape page] :as props}]
|
||||
[{:keys [section shapes page] :as props}]
|
||||
(let [locale (mf/deref i18n/locale)]
|
||||
[:div.tool-window
|
||||
[:div.tool-window-content
|
||||
|
@ -116,28 +117,23 @@
|
|||
:title (t locale "workspace.options.design")}
|
||||
[:div.element-options
|
||||
[:& align-options]
|
||||
(if (= (count selected) 1)
|
||||
[:& shape-options {:shape shape :page page}]
|
||||
[:& page/options {:page page}])]]
|
||||
(case (count shapes)
|
||||
0 [:& page/options {:page page}]
|
||||
1 [:& shape-options {:shape (first shapes)}]
|
||||
[:& multiple/options {:shapes shapes}])]]
|
||||
|
||||
[:& tab-element {:id :prototype
|
||||
:title (t locale "workspace.options.prototype")}
|
||||
[:div.element-options
|
||||
[:& interactions-menu {:shape shape}]]]]]]))
|
||||
[:& interactions-menu {:shape (first shapes)}]]]]]]))
|
||||
|
||||
|
||||
(mf/defc options-toolbox
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [page local] :as props}]
|
||||
(let [selected (:selected local)
|
||||
section (:options-mode local)
|
||||
shape-id (first selected)
|
||||
page-id (:id page)
|
||||
shape-iref (-> (mf/deps shape-id page-id)
|
||||
(mf/use-memo #(refs/object-by-id shape-id)))
|
||||
shape (mf/deref shape-iref)]
|
||||
[:& options-content {:selected selected
|
||||
:shape shape
|
||||
(let [section (:options-mode local)
|
||||
shapes (mf/deref refs/selected-objects)]
|
||||
[:& options-content {:shapes shapes
|
||||
:page page
|
||||
:section section}]))
|
||||
|
||||
|
|
|
@ -10,14 +10,24 @@
|
|||
(ns uxbox.main.ui.workspace.sidebar.options.circle
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[uxbox.main.ui.workspace.sidebar.options.fill :refer [fill-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.measures :refer [measures-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-menu]]))
|
||||
[uxbox.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]]))
|
||||
|
||||
(mf/defc options
|
||||
[{:keys [shape] :as props}]
|
||||
[:div
|
||||
[:& measures-menu {:shape shape
|
||||
:options #{:size :position :rotation}}]
|
||||
[:& fill-menu {:shape shape}]
|
||||
[:& stroke-menu {:shape shape}]])
|
||||
(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
|
||||
:options #{:size :position :rotation}}]
|
||||
[:& fill-menu {:ids ids
|
||||
:type type
|
||||
:values (select-keys shape fill-attrs)}]
|
||||
[:& stroke-menu {:ids ids
|
||||
:type type
|
||||
:values stroke-values}]]))
|
||||
|
|
|
@ -10,35 +10,43 @@
|
|||
(ns uxbox.main.ui.workspace.sidebar.options.fill
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[uxbox.main.data.workspace :as udw]
|
||||
[uxbox.main.data.workspace.common :as dwc]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
|
||||
[uxbox.util.object :as obj]
|
||||
[uxbox.util.i18n :as i18n :refer [tr t]]))
|
||||
|
||||
(def fill-attrs [:fill-color :fill-opacity])
|
||||
|
||||
(defn- fill-menu-memo-equals?
|
||||
[np op]
|
||||
(let [new-shape (obj/get np "shape")
|
||||
old-shape (obj/get op "shape")]
|
||||
(and (= (:id new-shape)
|
||||
(:id old-shape))
|
||||
(identical? (:fill-color new-shape)
|
||||
(:fill-color old-shape))
|
||||
(identical? (:fill-opacity new-shape)
|
||||
(:fill-opacity old-shape)))))
|
||||
(let [new-ids (obj/get np "ids")
|
||||
old-ids (obj/get op "ids")
|
||||
new-values (obj/get np "values")
|
||||
old-values (obj/get op "values")]
|
||||
(and (= new-ids old-ids)
|
||||
(identical? (:fill-color new-values)
|
||||
(:fill-color old-values))
|
||||
(identical? (:fill-opacity new-values)
|
||||
(:fill-opacity old-values)))))
|
||||
|
||||
(mf/defc fill-menu
|
||||
{::mf/wrap [#(mf/memo' % fill-menu-memo-equals?)]}
|
||||
[{:keys [shape] :as props}]
|
||||
[{:keys [ids type values] :as props}]
|
||||
(let [locale (i18n/use-locale)
|
||||
color {:value (:fill-color shape)
|
||||
:opacity (:fill-opacity shape)}
|
||||
label (case type
|
||||
:multiple (t locale "workspace.options.selection-fill")
|
||||
:group (t locale "workspace.options.group-fill")
|
||||
(t locale "workspace.options.fill"))
|
||||
color {:value (:fill-color values)
|
||||
:opacity (:fill-opacity values)}
|
||||
handle-change-color (fn [value opacity]
|
||||
(let [change {:fill-color value
|
||||
:fill-opacity opacity}]
|
||||
(st/emit! (udw/update-shape (:id shape) change))))]
|
||||
(let [change #(cond-> %
|
||||
value (assoc :fill-color value)
|
||||
opacity (assoc :fill-opacity opacity))]
|
||||
(st/emit! (dwc/update-shapes ids change))))]
|
||||
[:div.element-set
|
||||
[:div.element-set-title (t locale "workspace.options.fill")]
|
||||
[:div.element-set-title label]
|
||||
[:div.element-set-content
|
||||
[:& color-row {:value color
|
||||
[:& color-row {:color color
|
||||
:on-change handle-change-color}]]]))
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
[uxbox.main.data.workspace :as udw]
|
||||
[uxbox.main.ui.icons :as i]
|
||||
[uxbox.main.ui.components.dropdown :refer [dropdown]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.fill :refer [fill-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.frame-grid :refer [frame-grid]]))
|
||||
|
||||
(declare +size-presets+)
|
||||
|
@ -33,8 +33,8 @@
|
|||
|
||||
on-preset-selected
|
||||
(fn [width height]
|
||||
(st/emit! (udw/update-dimensions (:id shape) :width width)
|
||||
(udw/update-dimensions (:id shape) :height height)))
|
||||
(st/emit! (udw/update-dimensions [(:id shape)] :width width)
|
||||
(udw/update-dimensions [(:id shape)] :height height)))
|
||||
|
||||
on-orientation-clicked
|
||||
(fn [orientation]
|
||||
|
@ -42,19 +42,19 @@
|
|||
height (:height shape)
|
||||
new-width (if (= orientation :horiz) (max width height) (min width height))
|
||||
new-height (if (= orientation :horiz) (min width height) (max width height))]
|
||||
(st/emit! (udw/update-dimensions (:id shape) :width new-width)
|
||||
(udw/update-dimensions (:id shape) :height new-height))))
|
||||
(st/emit! (udw/update-dimensions [(:id shape)] :width new-width)
|
||||
(udw/update-dimensions [(:id shape)] :height new-height))))
|
||||
|
||||
on-size-change
|
||||
(fn [event attr]
|
||||
(let [value (-> (dom/get-target event)
|
||||
(dom/get-value)
|
||||
(d/parse-integer 0))]
|
||||
(st/emit! (udw/update-dimensions (:id shape) attr value))))
|
||||
(st/emit! (udw/update-dimensions [(:id shape)] attr value))))
|
||||
|
||||
on-proportion-lock-change
|
||||
(fn [event]
|
||||
(st/emit! (udw/toggle-shape-proportion-lock (:id shape))))
|
||||
(st/emit! (udw/set-shape-proportion-lock (:id shape) (not (:proportion-lock shape)))))
|
||||
|
||||
on-position-change
|
||||
(fn [event attr]
|
||||
|
@ -200,9 +200,16 @@
|
|||
|
||||
(mf/defc options
|
||||
[{:keys [shape] :as props}]
|
||||
[:div
|
||||
(let [ids [(:id shape)]
|
||||
type (:type shape)
|
||||
stroke-values (select-keys shape stroke-attrs)]
|
||||
[:*
|
||||
[:& measures-menu {:shape shape}]
|
||||
[:& fill-menu {:shape shape}]
|
||||
[:& stroke-menu {:shape shape}]
|
||||
[:& frame-grid {:shape shape}]])
|
||||
[:& fill-menu {:ids ids
|
||||
:type type
|
||||
:values (select-keys shape fill-attrs)}]
|
||||
[:& stroke-menu {:ids ids
|
||||
:type type
|
||||
:values stroke-values}]
|
||||
[:& frame-grid {:shape shape}]]))
|
||||
|
||||
|
|
|
@ -218,7 +218,7 @@
|
|||
:value (:margin params)
|
||||
:on-change (handle-change :params :margin)}]])
|
||||
|
||||
[:& color-row {:value (:color params)
|
||||
[:& color-row {:color (:color params)
|
||||
:on-change handle-change-color}]
|
||||
[:div.row-flex
|
||||
[:button.btn-options {:disabled is-default
|
||||
|
|
|
@ -11,11 +11,28 @@
|
|||
(ns uxbox.main.ui.workspace.sidebar.options.group
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[uxbox.main.ui.workspace.sidebar.options.measures :refer [measures-menu]]))
|
||||
[uxbox.main.refs :as refs]
|
||||
[uxbox.main.ui.workspace.sidebar.options.multiple :refer [get-multi]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]]))
|
||||
|
||||
(mf/defc options
|
||||
[{:keys [shape] :as props}]
|
||||
[:div
|
||||
[:& measures-menu {:options #{:position :rotation}
|
||||
:shape shape}]])
|
||||
(let [child-ids (:shapes shape)
|
||||
children (mf/deref (refs/objects-by-id child-ids))
|
||||
type (:type shape)
|
||||
measure-values (select-keys shape measure-attrs)
|
||||
fill-values (get-multi children fill-attrs)
|
||||
stroke-values (get-multi children stroke-attrs)]
|
||||
[:*
|
||||
[:& measures-menu {:ids (:id shape)
|
||||
:type type
|
||||
:values measure-values}]
|
||||
[:& fill-menu {:ids child-ids
|
||||
:type type
|
||||
:values fill-values}]
|
||||
[:& stroke-menu {:ids child-ids
|
||||
:type type
|
||||
:values stroke-values}]]))
|
||||
|
||||
|
|
|
@ -10,13 +10,23 @@
|
|||
(ns uxbox.main.ui.workspace.sidebar.options.icon
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[uxbox.main.ui.workspace.sidebar.options.measures :refer [measures-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.fill :refer [fill-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-menu]]))
|
||||
[uxbox.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]]))
|
||||
|
||||
(mf/defc options
|
||||
[{:keys [shape] :as props}]
|
||||
[:div
|
||||
[:& measures-menu {:shape shape}]
|
||||
[:& fill-menu {:shape shape}]
|
||||
[:& stroke-menu {:shape shape}]])
|
||||
(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}]]))
|
||||
|
|
|
@ -10,9 +10,14 @@
|
|||
(ns uxbox.main.ui.workspace.sidebar.options.image
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[uxbox.main.ui.workspace.sidebar.options.measures :refer [measures-menu]]))
|
||||
[uxbox.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]]))
|
||||
|
||||
(mf/defc options
|
||||
[{:keys [shape] :as props}]
|
||||
[:div
|
||||
[:& measures-menu {:shape shape}]])
|
||||
(let [ids [(:id shape)]
|
||||
type (:type shape)
|
||||
measure-values (select-keys shape measure-attrs)]
|
||||
[:*
|
||||
[:& measures-menu {:ids ids
|
||||
:type type
|
||||
:values measure-values}]]))
|
||||
|
|
|
@ -15,32 +15,58 @@
|
|||
[uxbox.main.refs :as refs]
|
||||
[uxbox.common.data :as d]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.util.data :refer [classnames]]
|
||||
[uxbox.common.geom.shapes :as gsh]
|
||||
[uxbox.common.geom.point :as gpt]
|
||||
[uxbox.main.data.workspace :as udw]
|
||||
[uxbox.main.data.workspace.common :as dwc]
|
||||
[uxbox.common.math :as math]
|
||||
[uxbox.util.i18n :refer [t] :as i18n]))
|
||||
|
||||
(def measure-attrs [:proportion-lock :width :height :x :y :rotation :rx :ry :selrect])
|
||||
|
||||
(defn attr->string [attr values]
|
||||
(let [value (attr values)]
|
||||
(if (= value :multiple)
|
||||
""
|
||||
(str (-> value
|
||||
(d/coalesce 0)
|
||||
(math/precision 2))))))
|
||||
|
||||
;; -- User/drawing coords
|
||||
(mf/defc measures-menu
|
||||
[{:keys [shape options] :as props}]
|
||||
[{:keys [options ids values] :as props}]
|
||||
(let [options (or options #{:size :position :rotation :radius})
|
||||
locale (i18n/use-locale)
|
||||
frame (deref (refs/object-by-id (:frame-id shape)))
|
||||
old-shape shape
|
||||
shape (->> shape
|
||||
(gsh/transform-shape frame))
|
||||
|
||||
old-shapes (deref (refs/objects-by-id ids))
|
||||
frames (map #(deref (refs/object-by-id (:frame-id %))) old-shapes)
|
||||
shapes (map gsh/transform-shape frames old-shapes)
|
||||
|
||||
values (cond-> values
|
||||
(not= (:x values) :multiple) (assoc :x (:x (:selrect (first shapes))))
|
||||
(not= (:y values) :multiple) (assoc :y (:y (:selrect (first shapes)))))
|
||||
|
||||
proportion-lock (:proportion-lock values)
|
||||
|
||||
on-size-change
|
||||
(fn [event attr]
|
||||
(let [value (-> (dom/get-target event)
|
||||
(dom/get-value)
|
||||
(d/parse-integer 0))]
|
||||
(st/emit! (udw/update-dimensions (:id shape) attr value))))
|
||||
(st/emit! (udw/update-dimensions ids attr value))))
|
||||
|
||||
on-proportion-lock-change
|
||||
(fn [event]
|
||||
(st/emit! (udw/toggle-shape-proportion-lock (:id shape))))
|
||||
(let [new-lock (if (= proportion-lock :multiple) true (not proportion-lock))]
|
||||
(run! #(st/emit! (udw/set-shape-proportion-lock % new-lock)) ids)))
|
||||
|
||||
do-position-change
|
||||
(fn [shape' frame' value attr]
|
||||
(let [from (-> shape' :selrect attr)
|
||||
to (+ value (attr frame'))
|
||||
target (+ (attr shape') (- to from))]
|
||||
(st/emit! (udw/update-position (:id shape') {attr target}))))
|
||||
|
||||
on-position-change
|
||||
(fn [event attr]
|
||||
|
@ -48,31 +74,37 @@
|
|||
(dom/get-value)
|
||||
(d/parse-integer 0))]
|
||||
(when value
|
||||
(let [from (-> shape :selrect attr)
|
||||
to (+ value (attr frame))
|
||||
target (+ (attr shape) (- to from))]
|
||||
(st/emit! (udw/update-position (:id shape) {attr target}))))))
|
||||
(doall (map #(do-position-change %1 %2 value attr) shapes frames)))))
|
||||
|
||||
do-rotation-change
|
||||
(fn [shape' old-shape' value]
|
||||
(st/emit! (udw/set-rotation (- value (:rotation shape')) [old-shape'])
|
||||
(udw/apply-modifiers #{(:id shape')})))
|
||||
|
||||
on-rotation-change
|
||||
(fn [event]
|
||||
(let [value (-> (dom/get-target event)
|
||||
(dom/get-value)
|
||||
(d/parse-integer 0))]
|
||||
(st/emit! (udw/set-rotation (- value (:rotation shape)) [old-shape])
|
||||
(udw/apply-modifiers #{(:id shape)}))))
|
||||
(doall (map #(do-rotation-change %1 %2 value) shapes old-shapes))))
|
||||
|
||||
on-radius-change
|
||||
(fn [event]
|
||||
(let [value (-> (dom/get-target event)
|
||||
(dom/get-value)
|
||||
(d/parse-integer 0))]
|
||||
(st/emit! (udw/update-shape (:id shape) {:rx value :ry value}))))
|
||||
(st/emit! (dwc/update-shapes-recursive
|
||||
ids
|
||||
#(if (:rx %)
|
||||
(assoc % :rx value :ry value)
|
||||
%)))))
|
||||
|
||||
on-width-change #(on-size-change % :width)
|
||||
on-height-change #(on-size-change % :height)
|
||||
on-pos-x-change #(on-position-change % :x)
|
||||
on-pos-y-change #(on-position-change % :y)
|
||||
select-all #(-> % (dom/get-target) (.select))]
|
||||
|
||||
[:div.element-set
|
||||
[:div.element-set-content
|
||||
|
||||
|
@ -80,50 +112,50 @@
|
|||
(when (options :size)
|
||||
[:div.row-flex
|
||||
[:span.element-set-subtitle (t locale "workspace.options.size")]
|
||||
[:div.lock-size {:class (when (:proportion-lock shape) "selected")
|
||||
[:div.lock-size {:class (classnames
|
||||
:selected (true? proportion-lock)
|
||||
:disabled (= proportion-lock :multiple))
|
||||
:on-click on-proportion-lock-change}
|
||||
(if (:proportion-lock shape)
|
||||
(if proportion-lock
|
||||
i/lock
|
||||
i/unlock)]
|
||||
[:div.input-element.width
|
||||
[:input.input-text {:type "number"
|
||||
:min "0"
|
||||
:no-validate true
|
||||
:placeholder "--"
|
||||
:on-click select-all
|
||||
:on-change on-width-change
|
||||
:value (str (-> (:width shape)
|
||||
(d/coalesce 0)
|
||||
(math/precision 2)))}]]
|
||||
:value (attr->string :width values)}]]
|
||||
|
||||
|
||||
[:div.input-element.height
|
||||
[:input.input-text {:type "number"
|
||||
:min "0"
|
||||
:no-validate true
|
||||
:placeholder "--"
|
||||
:on-click select-all
|
||||
:on-change on-height-change
|
||||
:value (str (-> (:height shape)
|
||||
(d/coalesce 0)
|
||||
(math/precision 2)))}]]])
|
||||
:value (attr->string :height values)}]]])
|
||||
|
||||
;; POSITION
|
||||
(when (options :position)
|
||||
[:div.row-flex
|
||||
[:span.element-set-subtitle (t locale "workspace.options.position")]
|
||||
[:div.input-element.Xaxis
|
||||
[:input.input-text {:placeholder "x"
|
||||
:type "number"
|
||||
[:input.input-text {:type "number"
|
||||
:no-validate true
|
||||
:placeholder "--"
|
||||
:on-click select-all
|
||||
:on-change on-pos-x-change
|
||||
:value (-> shape :selrect :x (math/precision 2))}]]
|
||||
:value (attr->string :x values)}]]
|
||||
[:div.input-element.Yaxis
|
||||
[:input.input-text {:placeholder "y"
|
||||
:type "number"
|
||||
[:input.input-text {:type "number"
|
||||
:no-validate true
|
||||
:placeholder "--"
|
||||
:on-click select-all
|
||||
:on-change on-pos-y-change
|
||||
:value (-> shape :selrect :y (math/precision 2))}]]])
|
||||
:value (attr->string :y values)}]]])
|
||||
|
||||
;; ROTATION
|
||||
(when (options :rotation)
|
||||
|
@ -131,16 +163,14 @@
|
|||
[:span.element-set-subtitle (t locale "workspace.options.rotation")]
|
||||
[:div.input-element.degrees
|
||||
[:input.input-text
|
||||
{:placeholder ""
|
||||
:type "number"
|
||||
{:type "number"
|
||||
:no-validate true
|
||||
:min "0"
|
||||
:max "359"
|
||||
:placeholder "--"
|
||||
:on-click select-all
|
||||
:on-change on-rotation-change
|
||||
:value (str (-> (:rotation shape)
|
||||
(d/coalesce 0)
|
||||
(math/precision 2)))}]]
|
||||
:value (attr->string :rotation values)}]]
|
||||
[:input.slidebar
|
||||
{:type "range"
|
||||
:min "0"
|
||||
|
@ -148,9 +178,7 @@
|
|||
:step "10"
|
||||
:no-validate true
|
||||
:on-change on-rotation-change
|
||||
:value (str (-> (:rotation shape)
|
||||
(d/coalesce 0)
|
||||
(math/precision 2)))}]])
|
||||
:value (attr->string :rotation values)}]])
|
||||
|
||||
;; RADIUS
|
||||
(when (options :radius)
|
||||
|
@ -158,11 +186,9 @@
|
|||
[:span.element-set-subtitle (t locale "workspace.options.radius")]
|
||||
[:div.input-element.pixels
|
||||
[:input.input-text
|
||||
{:placeholder "rx"
|
||||
:type "number"
|
||||
{:type "number"
|
||||
:placeholder "--"
|
||||
:on-click select-all
|
||||
:on-change on-radius-change
|
||||
:value (str (-> (:rx shape)
|
||||
(d/coalesce 0)
|
||||
(math/precision 2)))}]]
|
||||
:value (attr->string :rx values)}]]
|
||||
[:div.input-element]])]]))
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
;; 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 uxbox.main.ui.workspace.sidebar.options.multiple
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[uxbox.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]]))
|
||||
|
||||
(defn get-multi
|
||||
[shapes attrs]
|
||||
(let [combine-value #(if (= %1 %2) %1 :multiple)
|
||||
|
||||
combine-values (fn [attrs shape values]
|
||||
(map #(combine-value (get shape %) (get values %)) attrs))
|
||||
|
||||
reducer (fn [result shape]
|
||||
(zipmap attrs (combine-values attrs shape result)))]
|
||||
|
||||
(reduce reducer (select-keys (first shapes) attrs) (rest shapes))))
|
||||
|
||||
|
||||
(mf/defc options
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [shapes] :as props}]
|
||||
(let [ids (map :id shapes)
|
||||
measure-values (get-multi shapes measure-attrs)
|
||||
fill-values (get-multi shapes fill-attrs)
|
||||
stroke-values (get-multi shapes stroke-attrs)]
|
||||
[:*
|
||||
[:& measures-menu {:ids ids
|
||||
:type :multiple
|
||||
:values measure-values}]
|
||||
[:& fill-menu {:ids ids
|
||||
:type :multiple
|
||||
:values fill-values}]
|
||||
[:& stroke-menu {:ids ids
|
||||
:type :multiple
|
||||
:values stroke-values}]]))
|
||||
|
|
@ -37,8 +37,7 @@
|
|||
[:div.element-set-title (t locale "workspace.options.canvas-background")]
|
||||
[:div.element-set-content
|
||||
[:& color-row {:disable-opacity true
|
||||
:value {:value (get options :background "#E8E9EA")
|
||||
:color {:value (get options :background "#E8E9EA")
|
||||
:opacity 1}
|
||||
:on-change handle-change-color}]]])
|
||||
)
|
||||
:on-change handle-change-color}]]]))
|
||||
|
||||
|
|
|
@ -11,11 +11,18 @@
|
|||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[uxbox.common.data :as d]
|
||||
[uxbox.main.ui.workspace.sidebar.options.fill :refer [fill-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-menu]]))
|
||||
[uxbox.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]]))
|
||||
|
||||
(mf/defc options
|
||||
[{:keys [shape] :as props}]
|
||||
[:div
|
||||
[:& fill-menu {:shape shape}]
|
||||
[:& stroke-menu {:shape shape}]])
|
||||
(let [ids [(:id shape)]
|
||||
type (:type shape)
|
||||
stroke-values (select-keys shape stroke-attrs)]
|
||||
[:*
|
||||
[:& fill-menu {:ids ids
|
||||
:type type
|
||||
:values (select-keys shape fill-attrs)}]
|
||||
[:& stroke-menu {:ids ids
|
||||
:type type
|
||||
:values stroke-values}]]))
|
||||
|
|
|
@ -10,14 +10,26 @@
|
|||
(ns uxbox.main.ui.workspace.sidebar.options.rect
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[uxbox.main.ui.workspace.sidebar.options.fill :refer [fill-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.measures :refer [measures-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-menu]]))
|
||||
[uxbox.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.fill :refer [fill-attrs fill-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-attrs stroke-menu]]))
|
||||
|
||||
(mf/defc options
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [shape] :as props}]
|
||||
[:div
|
||||
[:& measures-menu {:shape shape}]
|
||||
[:& fill-menu {:shape shape}]
|
||||
[:& stroke-menu {:shape shape}]])
|
||||
(let [ids [(:id shape)]
|
||||
type (:type shape)
|
||||
measure-values (select-keys shape measure-attrs)
|
||||
fill-values (select-keys shape fill-attrs)
|
||||
stroke-values (select-keys shape stroke-attrs)]
|
||||
[:*
|
||||
[:& measures-menu {:ids ids
|
||||
:type type
|
||||
:values measure-values}]
|
||||
[:& fill-menu {:ids ids
|
||||
:type type
|
||||
:values fill-values}]
|
||||
[:& stroke-menu {:ids ids
|
||||
:type type
|
||||
:values stroke-values}]]))
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
[rumext.alpha :as mf]
|
||||
[uxbox.common.math :as math]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.util.data :refer [classnames]]
|
||||
[uxbox.util.i18n :as i18n :refer [tr]]
|
||||
[uxbox.main.ui.modal :as modal]
|
||||
[uxbox.main.ui.workspace.colorpicker :refer [colorpicker-modal]]
|
||||
[uxbox.common.data :as d]))
|
||||
|
@ -29,76 +31,99 @@
|
|||
:disable-opacity disable-opacity}]
|
||||
(modal/show! colorpicker-modal props))))
|
||||
|
||||
(defn value-to-background [value]
|
||||
(if (= value :multiple) "transparent" value))
|
||||
|
||||
(defn remove-hash [value]
|
||||
(if (= value :multiple) "" (subs value 1)))
|
||||
|
||||
(defn append-hash [value]
|
||||
(str "#" value))
|
||||
|
||||
(defn opacity->string [opacity]
|
||||
(if (and opacity (not= opacity ""))
|
||||
(if (= opacity :multiple)
|
||||
""
|
||||
(str (-> opacity
|
||||
(d/coalesce 1)
|
||||
(* 100)
|
||||
(math/round)))
|
||||
""))
|
||||
(math/round)))))
|
||||
|
||||
(defn string->opacity [opacity-str]
|
||||
(when (and opacity-str (not= "" opacity-str))
|
||||
(-> opacity-str
|
||||
(d/parse-integer 1)
|
||||
(/ 100))))
|
||||
(-> opacity-str
|
||||
(d/parse-integer 1)
|
||||
(/ 100)))
|
||||
|
||||
(mf/defc color-row [{:keys [value on-change disable-opacity]}]
|
||||
(let [default-value {:value "#000000" :opacity 1}
|
||||
(defn remove-multiple [v]
|
||||
(if (= v :multiple) nil v))
|
||||
|
||||
parse-value (fn [value]
|
||||
(-> (merge default-value value)
|
||||
(mf/defc color-row [{:keys [color on-change disable-opacity]}]
|
||||
(let [default-color {:value "#000000" :opacity 1}
|
||||
|
||||
parse-color (fn [color]
|
||||
(-> (merge default-color color)
|
||||
(update :value #(or % "#000000"))
|
||||
(update :opacity #(or % 1))))
|
||||
|
||||
state (mf/use-state (parse-value value))
|
||||
state (mf/use-state (parse-color color))
|
||||
|
||||
change-color (fn [new-value]
|
||||
(let [{:keys [value opacity]} @state]
|
||||
(swap! state assoc :value new-value)
|
||||
(when on-change (on-change new-value opacity))))
|
||||
value (:value @state)
|
||||
opacity (:opacity @state)
|
||||
|
||||
change-value (fn [new-value]
|
||||
(swap! state assoc :value new-value)
|
||||
(when on-change (on-change new-value (remove-multiple opacity))))
|
||||
|
||||
change-opacity (fn [new-opacity]
|
||||
(let [{:keys [value opacity]} @state]
|
||||
(swap! state assoc :opacity new-opacity)
|
||||
(when (and new-opacity on-change) (on-change value new-opacity))))
|
||||
(swap! state assoc :opacity new-opacity)
|
||||
(when on-change (on-change (remove-multiple value) new-opacity)))
|
||||
|
||||
handle-pick-color (fn [color opacity]
|
||||
(reset! state {:value color :opacity opacity})
|
||||
(when on-change (on-change color opacity)))
|
||||
handle-pick-color (fn [new-value new-opacity]
|
||||
(reset! state {:value new-value :opacity new-opacity})
|
||||
(when on-change (on-change new-value new-opacity)))
|
||||
|
||||
handle-value-change (fn [event]
|
||||
(let [target (dom/get-target event)]
|
||||
(when (dom/valid? target)
|
||||
(-> target
|
||||
dom/get-value
|
||||
append-hash
|
||||
change-value))))
|
||||
|
||||
handle-input-color-change (fn [event]
|
||||
(let [target (dom/get-target event)
|
||||
value (dom/get-value target)]
|
||||
(when (dom/valid? target)
|
||||
(change-color (str "#" value)))))
|
||||
handle-opacity-change (fn [event]
|
||||
(-> event
|
||||
dom/get-target
|
||||
dom/get-value
|
||||
string->opacity
|
||||
change-opacity))
|
||||
select-all #(-> % (dom/get-target) (.select))]
|
||||
(let [target (dom/get-target event)]
|
||||
(when (dom/valid? target)
|
||||
(-> target
|
||||
dom/get-value
|
||||
string->opacity
|
||||
change-opacity))))
|
||||
|
||||
select-all (fn [event]
|
||||
(dom/select-text! (dom/get-target event)))]
|
||||
|
||||
(mf/use-effect
|
||||
(mf/deps value)
|
||||
#(reset! state (parse-value value)))
|
||||
(mf/deps color)
|
||||
#(reset! state (parse-color color)))
|
||||
;; is this necessary?
|
||||
|
||||
[:div.row-flex.color-data
|
||||
[:span.color-th
|
||||
{:style {:background-color (-> @state :value)}
|
||||
:on-click (color-picker-callback @state handle-pick-color disable-opacity)}]
|
||||
{:style {:background-color (-> value value-to-background)}
|
||||
:on-click (color-picker-callback @state handle-pick-color disable-opacity)}
|
||||
(when (= value :multiple) "?")]
|
||||
|
||||
[:div.color-info
|
||||
[:input {:value (-> @state :value (subs 1))
|
||||
[:input {:value (-> value remove-hash)
|
||||
:pattern "^[0-9a-fA-F]{0,6}$"
|
||||
:placeholder (tr "settings.multiple")
|
||||
:on-click select-all
|
||||
:on-change handle-input-color-change}]]
|
||||
:on-change handle-value-change}]]
|
||||
|
||||
(when (not disable-opacity)
|
||||
[:div.input-element.percentail
|
||||
[:div.input-element
|
||||
{:class (classnames :percentail (not= opacity :multiple))}
|
||||
[:input.input-text {:type "number"
|
||||
:value (-> @state :opacity opacity->string)
|
||||
:value (-> opacity opacity->string)
|
||||
:placeholder (tr "settings.multiple")
|
||||
:on-click select-all
|
||||
:on-change handle-opacity-change
|
||||
:min "0"
|
||||
|
@ -107,7 +132,7 @@
|
|||
#_[:input.slidebar {:type "range"
|
||||
:min "0"
|
||||
:max "100"
|
||||
:value (-> @state :opacity opacity->string)
|
||||
:value (-> opacity opacity->string)
|
||||
:step "1"
|
||||
:on-change handle-opacity-change}]]))
|
||||
|
||||
|
|
|
@ -9,110 +9,141 @@
|
|||
|
||||
(ns uxbox.main.ui.workspace.sidebar.options.stroke
|
||||
(:require
|
||||
[cuerdas.core :as str]
|
||||
[rumext.alpha :as mf]
|
||||
[uxbox.common.data :as d]
|
||||
[uxbox.main.ui.icons :as i]
|
||||
[uxbox.main.data.workspace :as udw]
|
||||
[uxbox.main.data.workspace.common :as dwc]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.ui.modal :as modal]
|
||||
[uxbox.main.ui.workspace.colorpicker :refer [colorpicker-modal]]
|
||||
[uxbox.util.data :refer [classnames]]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.util.object :as obj]
|
||||
[uxbox.util.i18n :as i18n :refer [tr t]]
|
||||
[uxbox.util.i18n :as i18n :refer [tr t]]
|
||||
[uxbox.common.math :as math]
|
||||
[uxbox.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]))
|
||||
|
||||
(def stroke-attrs [:stroke-style :stroke-alignment :stroke-width :stroke-color :stroke-opacity])
|
||||
|
||||
(defn- stroke-menu-memo-equals?
|
||||
[np op]
|
||||
(let [new-shape (obj/get np "shape")
|
||||
old-shape (obj/get op "shape")]
|
||||
(and (= (:id new-shape)
|
||||
(:id old-shape))
|
||||
(identical? (:stroke-style new-shape)
|
||||
(:stroke-style old-shape))
|
||||
(identical? (:stroke-alignment new-shape)
|
||||
(:stroke-alignment old-shape))
|
||||
(identical? (:stroke-width new-shape)
|
||||
(:stroke-width old-shape))
|
||||
(identical? (:stroke-color new-shape)
|
||||
(:stroke-color old-shape))
|
||||
(identical? (:stroke-opacity new-shape)
|
||||
(:stroke-opacity old-shape)))))
|
||||
(let [new-ids (obj/get np "ids")
|
||||
old-ids (obj/get op "ids")
|
||||
new-values (obj/get np "values")
|
||||
old-values (obj/get op "values")]
|
||||
(and (= new-ids old-ids)
|
||||
(identical? (:stroke-style new-values)
|
||||
(:stroke-style old-values))
|
||||
(identical? (:stroke-alignment new-values)
|
||||
(:stroke-alignment old-values))
|
||||
(identical? (:stroke-width new-values)
|
||||
(:stroke-width old-values))
|
||||
(identical? (:stroke-color new-values)
|
||||
(:stroke-color old-values))
|
||||
(identical? (:stroke-opacity new-values)
|
||||
(:stroke-opacity old-values)))))
|
||||
|
||||
(defn width->string [width]
|
||||
(if (= width :multiple)
|
||||
""
|
||||
(str (-> width
|
||||
(d/coalesce 1)
|
||||
(math/round)))))
|
||||
|
||||
(defn enum->string [value]
|
||||
(if (= value :multiple)
|
||||
""
|
||||
(pr-str value)))
|
||||
|
||||
(mf/defc stroke-menu
|
||||
{::mf/wrap [#(mf/memo' % stroke-menu-memo-equals?)]}
|
||||
[{:keys [shape] :as props}]
|
||||
[{:keys [ids type values] :as props}]
|
||||
(let [locale (i18n/use-locale)
|
||||
show-options (not= (:stroke-style shape) :none)
|
||||
label (case type
|
||||
:multiple (t locale "workspace.options.selection-stroke")
|
||||
:group (t locale "workspace.options.group-stroke")
|
||||
(t locale "workspace.options.stroke"))
|
||||
|
||||
show-options (not= (:stroke-style values :none) :none)
|
||||
|
||||
current-stroke-color {:value (:stroke-color values)
|
||||
:opacity (:stroke-opacity values)}
|
||||
|
||||
handle-change-stroke-color
|
||||
(fn [value opacity]
|
||||
(let [change #(cond-> %
|
||||
value (assoc :stroke-color value)
|
||||
opacity (assoc :stroke-opacity opacity))]
|
||||
(st/emit! (dwc/update-shapes ids change))))
|
||||
|
||||
on-stroke-style-change
|
||||
(fn [event]
|
||||
(let [value (-> (dom/get-target event)
|
||||
(dom/get-value)
|
||||
(d/read-string))]
|
||||
(st/emit! (udw/update-shape (:id shape) {:stroke-style value}))))
|
||||
(st/emit! (dwc/update-shapes ids #(assoc % :stroke-style value)))))
|
||||
|
||||
on-stroke-alignment-change
|
||||
(fn [event]
|
||||
(let [value (-> (dom/get-target event)
|
||||
(dom/get-value)
|
||||
(d/read-string))]
|
||||
(st/emit! (udw/update-shape (:id shape) {:stroke-alignment value}))))
|
||||
(when-not (str/empty? value)
|
||||
(st/emit! (dwc/update-shapes ids #(assoc % :stroke-alignment value))))))
|
||||
|
||||
on-stroke-width-change
|
||||
(fn [event]
|
||||
(let [value (-> (dom/get-target event)
|
||||
(dom/get-value)
|
||||
(d/parse-integer 0))]
|
||||
(st/emit! (udw/update-shape (:id shape) {:stroke-width value}))))
|
||||
(when-not (str/empty? value)
|
||||
(st/emit! (dwc/update-shapes ids #(assoc % :stroke-width value))))))
|
||||
|
||||
on-add-stroke
|
||||
(fn [event]
|
||||
(st/emit! (udw/update-shape (:id shape) {:stroke-style :solid
|
||||
(st/emit! (dwc/update-shapes ids #(assoc %
|
||||
:stroke-style :solid
|
||||
:stroke-color "#000000"
|
||||
:stroke-opacity 1})))
|
||||
:stroke-opacity 1))))
|
||||
|
||||
on-del-stroke
|
||||
(fn [event]
|
||||
(st/emit! (udw/update-shape (:id shape) {:stroke-style :none})))
|
||||
(st/emit! (dwc/update-shapes ids #(assoc % :stroke-style :none))))]
|
||||
|
||||
current-stroke-color {:value (:stroke-color shape)
|
||||
:opacity (:stroke-opacity shape)}
|
||||
|
||||
handle-change-stroke-color
|
||||
(fn [value opacity]
|
||||
(st/emit! (udw/update-shape (:id shape) {:stroke-color value
|
||||
:stroke-opacity opacity})))]
|
||||
|
||||
(if (not= :none (:stroke-style shape :none))
|
||||
(if show-options
|
||||
[:div.element-set
|
||||
[:div.element-set-title
|
||||
[:span (t locale "workspace.options.stroke")]
|
||||
[:span label]
|
||||
[:div.add-page {:on-click on-del-stroke} i/minus]]
|
||||
|
||||
[:div.element-set-content
|
||||
;; Stroke Color
|
||||
[:& color-row {:value current-stroke-color
|
||||
[:& color-row {:color current-stroke-color
|
||||
:on-change handle-change-stroke-color}]
|
||||
|
||||
;; Stroke Width, Alignment & Style
|
||||
[:div.row-flex
|
||||
[:div.input-element.pixels
|
||||
[:div.input-element
|
||||
{:class (classnames :pixels (not= (:stroke-width values) :multiple))}
|
||||
[:input.input-text {:type "number"
|
||||
:min "0"
|
||||
:value (str (-> (:stroke-width shape)
|
||||
(d/coalesce 1)
|
||||
(math/round)))
|
||||
:value (-> (:stroke-width values) width->string)
|
||||
:placeholder (t locale "settings.multiple")
|
||||
:on-change on-stroke-width-change}]]
|
||||
|
||||
[:select#style.input-select {:value (pr-str (:stroke-alignment shape))
|
||||
[:select#style.input-select {:value (enum->string (:stroke-alignment values))
|
||||
:on-change on-stroke-alignment-change}
|
||||
(when (= (:stroke-alignment values) :multiple)
|
||||
[:option {:value ""} "--"])
|
||||
[:option {:value ":center"} (t locale "workspace.options.stroke.center")]
|
||||
[:option {:value ":inner"} (t locale "workspace.options.stroke.inner")]
|
||||
[:option {:value ":outer"} (t locale "workspace.options.stroke.outer")]]
|
||||
|
||||
[:select#style.input-select {:value (pr-str (:stroke-style shape))
|
||||
[:select#style.input-select {:value (enum->string (:stroke-style values))
|
||||
:on-change on-stroke-style-change}
|
||||
(when (= (:stroke-style values) :multiple)
|
||||
[:option {:value ""} "--"])
|
||||
[: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")]
|
||||
|
@ -121,5 +152,6 @@
|
|||
;; NO STROKE
|
||||
[:div.element-set
|
||||
[:div.element-set-title
|
||||
[:span (t locale "workspace.options.stroke")]
|
||||
[:span label]
|
||||
[:div.add-page {:on-click on-add-stroke} i/close]]])))
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
[uxbox.main.data.workspace.texts :as dwt]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.refs :as refs]
|
||||
[uxbox.main.ui.workspace.sidebar.options.measures :refer [measures-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.measures :refer [measure-attrs measures-menu]]
|
||||
[uxbox.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.main.fonts :as fonts]
|
||||
|
@ -199,9 +199,8 @@
|
|||
:attrs {:fill value
|
||||
:opacity opacity}})))]
|
||||
|
||||
[:& color-row {:value current-color
|
||||
:on-change handle-change-color}]
|
||||
))
|
||||
[:& color-row {:color current-color
|
||||
:on-change handle-change-color}]))
|
||||
|
||||
(mf/defc spacing-options
|
||||
[{:keys [editor shape locale] :as props}]
|
||||
|
@ -384,7 +383,6 @@
|
|||
[:div.element-set-content
|
||||
[:& text-fill-options {:editor editor :shape shape}]]]
|
||||
|
||||
|
||||
[:div.element-set
|
||||
[:div.element-set-title (t locale "workspace.options.font-options")]
|
||||
[:div.element-set-content
|
||||
|
@ -397,6 +395,11 @@
|
|||
|
||||
(mf/defc options
|
||||
[{:keys [shape] :as props}]
|
||||
[:div
|
||||
[:& measures-menu {:shape shape}]
|
||||
[:& text-menu {:shape shape}]])
|
||||
(let [ids [(:id shape)]
|
||||
type (:type shape)
|
||||
measure-values (select-keys shape measure-attrs)]
|
||||
[:div
|
||||
[:& measures-menu {:ids ids
|
||||
:type type
|
||||
:values measure-values}]
|
||||
[:& text-menu {:shape shape}]]))
|
||||
|
|
Loading…
Add table
Reference in a new issue