mirror of
https://github.com/penpot/penpot.git
synced 2025-02-13 18:48:37 -05:00
✨ Context menu for booleans
This commit is contained in:
parent
fcc7b6791e
commit
74f3d551f2
9 changed files with 86 additions and 36 deletions
3
frontend/resources/images/icons/boolean-flatten.svg
Normal file
3
frontend/resources/images/icons/boolean-flatten.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
|
||||
<path d="M0 0v337.059h141.904C150.271 428.269 227.21 500 320.557 500 419.47 500 500 419.47 500 320.557c0-93.18-71.47-170.015-162.445-178.614V0H0zm32 32h273.555v109.791c-43.314 3.609-82.301 22.678-111.43 51.65L32 32.8V32zm273.555 141.867V303.85l-88.866-88.051c23.298-23.102 54.286-38.46 88.866-41.932zm32 .246C411.119 182.51 468 244.691 468 320.557c0 40.092-15.942 76.315-41.777 102.855l-88.668-87.855V174.113z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 485 B |
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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]]]))
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Add table
Reference in a new issue