diff --git a/frontend/resources/images/icons/boolean-flatten.svg b/frontend/resources/images/icons/boolean-flatten.svg new file mode 100644 index 000000000..f7816f8b5 --- /dev/null +++ b/frontend/resources/images/icons/boolean-flatten.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/resources/styles/main/partials/sidebar-align-options.scss b/frontend/resources/styles/main/partials/sidebar-align-options.scss index 2d3565c4a..c9ee61451 100644 --- a/frontend/resources/styles/main/partials/sidebar-align-options.scss +++ b/frontend/resources/styles/main/partials/sidebar-align-options.scss @@ -9,11 +9,11 @@ display: flex; border-bottom: solid 1px $color-gray-60; height: 40px; - padding: 0 $x-small; .align-group { + padding: 0 $x-small; display: flex; - justify-content: space-evenly; + justify-content: start; width: 50%; &:not(:last-child) { @@ -25,7 +25,12 @@ align-items: center; cursor: pointer; display: flex; + height: 30px; + justify-content: center; + margin: 5px 0; padding: $small $x-small; + width: 25%; + svg { height: 16px; width: 16px; diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 8f4e30599..7b5028fef 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -31,6 +31,7 @@ [app.main.data.workspace.libraries :as dwl] [app.main.data.workspace.notifications :as dwn] [app.main.data.workspace.path :as dwdp] + [app.main.data.workspace.path.shapes-to-path :as dwps] [app.main.data.workspace.persistence :as dwp] [app.main.data.workspace.selection :as dws] [app.main.data.workspace.state-helpers :as wsh] @@ -1994,3 +1995,6 @@ (d/export dwb/group-to-bool) (d/export dwb/bool-to-group) (d/export dwb/change-bool-type) + +;; Shapes to path +(d/export dwps/convert-selected-to-path) diff --git a/frontend/src/app/main/data/workspace/groups.cljs b/frontend/src/app/main/data/workspace/groups.cljs index f3f92c2b3..11605a13b 100644 --- a/frontend/src/app/main/data/workspace/groups.cljs +++ b/frontend/src/app/main/data/workspace/groups.cljs @@ -198,7 +198,7 @@ group-id (first selected) group (get objects group-id)] (when (and (= 1 (count selected)) - (= (:type group) :group)) + (contains? #{:group :bool} (:type group))) (let [[rchanges uchanges] (prepare-remove-group page-id group objects)] (rx/of (dch/commit-changes {:redo-changes rchanges diff --git a/frontend/src/app/main/ui/icons.cljs b/frontend/src/app/main/ui/icons.cljs index 35c5285d2..a0de63839 100644 --- a/frontend/src/app/main/ui/icons.cljs +++ b/frontend/src/app/main/ui/icons.cljs @@ -27,6 +27,7 @@ (def auto-width (icon-xref :auto-width)) (def boolean-difference (icon-xref :boolean-difference)) (def boolean-exclude (icon-xref :boolean-exclude)) +(def boolean-flatten (icon-xref :boolean-flatten)) (def boolean-intersection (icon-xref :boolean-intersection)) (def boolean-union (icon-xref :boolean-union)) (def box (icon-xref :box)) diff --git a/frontend/src/app/main/ui/workspace/context_menu.cljs b/frontend/src/app/main/ui/workspace/context_menu.cljs index b65f9d062..3ed95846f 100644 --- a/frontend/src/app/main/ui/workspace/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/context_menu.cljs @@ -10,7 +10,6 @@ [app.main.data.modal :as modal] [app.main.data.workspace :as dw] [app.main.data.workspace.libraries :as dwl] - [app.main.data.workspace.path.shapes-to-path :as dwpe] [app.main.data.workspace.shortcuts :as sc] [app.main.data.workspace.undo :as dwu] [app.main.refs :as refs] @@ -93,6 +92,21 @@ multiple? (> (count selected) 1) editable-shape? (#{:group :text :path} (:type shape)) + is-group? (and (some? shape) (= :group (:type shape))) + is-bool? (and (some? shape) (= :bool (:type shape))) + + set-bool + (fn [bool-type] + #(cond + (> (count selected) 1) + (st/emit! (dw/create-bool bool-type)) + + (and (= (count selected) 1) is-group?) + (st/emit! (dw/group-to-bool (:id shape) bool-type)) + + (and (= (count selected) 1) is-bool?) + (st/emit! (dw/change-bool-type (:id shape) bool-type)))) + current-file-id (mf/use-ctx ctx/current-file-id) do-duplicate (st/emitf dw/duplicate-selected) @@ -144,12 +158,8 @@ do-navigate-component-file (st/emitf (dwl/nav-to-component-file (:component-file shape))) - do-boolean-union (st/emitf (dw/create-bool :union)) - do-boolean-difference (st/emitf (dw/create-bool :difference)) - do-boolean-intersection (st/emitf (dw/create-bool :intersection)) - do-boolean-exclude (st/emitf (dw/create-bool :exclude)) - do-transform-to-path (st/emitf (dwpe/convert-selected-to-path)) - ] + do-transform-to-path (st/emitf (dw/convert-selected-to-path)) + do-flatten (st/emitf (dw/convert-selected-to-path))] [:* [:& menu-entry {:title (tr "workspace.shape.menu.copy") :shortcut (sc/get-tooltip :copy) @@ -198,7 +208,7 @@ :on-click do-flip-horizontal}] [:& menu-separator]]) - (when (and single? (= (:type shape) :group)) + (when (and single? (or is-bool? is-group?)) [:* [:& menu-entry {:title (tr "workspace.shape.menu.ungroup") :shortcut (sc/get-tooltip :ungroup) @@ -216,26 +226,29 @@ :shortcut (sc/get-tooltip :start-editing) :on-click do-start-editing}]) - [:& menu-entry {:title "Transform to path" + [:& menu-entry {:title (tr "workspace.shape.menu.transform-to-path") :on-click do-transform-to-path}] - [:& menu-entry {:title (tr "workspace.shape.menu.path")} - [:& menu-entry {:title (tr "workspace.shape.menu.union") - :shortcut (sc/get-tooltip :boolean-union) - :on-click do-boolean-union}] - [:& menu-entry {:title (tr "workspace.shape.menu.difference") - :shortcut (sc/get-tooltip :boolean-difference) - :on-click do-boolean-difference}] - [:& menu-entry {:title (tr "workspace.shape.menu.intersection") - :shortcut (sc/get-tooltip :boolean-intersection) - :on-click do-boolean-intersection}] - [:& menu-entry {:title (tr "workspace.shape.menu.exclude") - :shortcut (sc/get-tooltip :boolean-exclude) - :on-click do-boolean-exclude}] + (when (or multiple? (and single? (or is-group? is-bool?))) + [:& menu-entry {:title (tr "workspace.shape.menu.path")} + [:& menu-entry {:title (tr "workspace.shape.menu.union") + :shortcut (sc/get-tooltip :boolean-union) + :on-click (set-bool :union)}] + [:& menu-entry {:title (tr "workspace.shape.menu.difference") + :shortcut (sc/get-tooltip :boolean-difference) + :on-click (set-bool :difference)}] + [:& menu-entry {:title (tr "workspace.shape.menu.intersection") + :shortcut (sc/get-tooltip :boolean-intersection) + :on-click (set-bool :intersection)}] + [:& menu-entry {:title (tr "workspace.shape.menu.exclude") + :shortcut (sc/get-tooltip :boolean-exclude) + :on-click (set-bool :exclude)}] - [:& menu-separator] - ;; TODO - [:& menu-entry {:title "Flatten"}]] + (when (and single? is-bool?) + [:* + [:& menu-separator] + [:& menu-entry {:title (tr "workspace.shape.menu.flatten") + :on-click do-flatten}]])]) (if (:hidden shape) [:& menu-entry {:title (tr "workspace.shape.menu.show") diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/booleans.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/booleans.cljs index 4f1137a60..64b287417 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/booleans.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/booleans.cljs @@ -17,9 +17,14 @@ (mf/defc booleans-options [] (let [selected (mf/deref refs/selected-objects) - disabled (or (empty? selected) - (and (<= (count selected) 1) - (not (contains? #{:group :bool} (:type (first selected)))))) + + disabled-bool-btns + (or (empty? selected) + (and (<= (count selected) 1) + (not (contains? #{:group :bool} (:type (first selected)))))) + + disabled-flatten + (empty? selected) head (first selected) is-group? (and (some? head) (= :group (:type head))) @@ -44,29 +49,36 @@ [:div.align-group [:div.align-button.tooltip.tooltip-bottom {:alt (tr "workspace.shape.menu.union") - :class (dom/classnames :disabled disabled + :class (dom/classnames :disabled disabled-bool-btns :selected (= head-bool-type :union)) :on-click (set-bool :union)} i/boolean-union] [:div.align-button.tooltip.tooltip-bottom {:alt (tr "workspace.shape.menu.difference") - :class (dom/classnames :disabled disabled + :class (dom/classnames :disabled disabled-bool-btns :selected (= head-bool-type :difference)) :on-click (set-bool :difference)} i/boolean-difference] [:div.align-button.tooltip.tooltip-bottom {:alt (tr "workspace.shape.menu.intersection") - :class (dom/classnames :disabled disabled + :class (dom/classnames :disabled disabled-bool-btns :selected (= head-bool-type :intersection)) :on-click (set-bool :intersection)} i/boolean-intersection] [:div.align-button.tooltip.tooltip-bottom {:alt (tr "workspace.shape.menu.exclude") - :class (dom/classnames :disabled disabled + :class (dom/classnames :disabled disabled-bool-btns :selected (= head-bool-type :exclude)) :on-click (set-bool :exclude)} - i/boolean-exclude]]])) + i/boolean-exclude]] + + [:div.align-group + [:div.align-button.tooltip.tooltip-bottom + {:alt (tr "workspace.shape.menu.flatten") + :class (dom/classnames :disabled disabled-flatten) + :on-click (st/emitf (dw/convert-selected-to-path))} + i/boolean-flatten]]])) diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 27c40c21c..f39b799f8 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -3130,3 +3130,9 @@ msgstr "Intersection" msgid "workspace.shape.menu.exclude" msgstr "Exclude" + +msgid "workspace.shape.menu.flatten" +msgstr "Flatten" + +msgid "workspace.shape.menu.transform-to-path" +msgstr "Transform to path" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index a1020f9c3..a0139d9e2 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -3015,3 +3015,9 @@ msgstr "Intersección" msgid "workspace.shape.menu.exclude" msgstr "Exclusión" + +msgid "workspace.shape.menu.flatten" +msgstr "Aplanar" + +msgid "workspace.shape.menu.transform-to-path" +msgstr "Convertir en vector"