mirror of
https://github.com/penpot/penpot.git
synced 2025-02-03 04:49:03 -05:00
🐛 Fixes some issues with bool shapes
This commit is contained in:
parent
99a6142134
commit
4c86d5cfe3
15 changed files with 96 additions and 67 deletions
|
@ -49,6 +49,8 @@
|
|||
(update :points move-points move-vec)
|
||||
(d/update-when :x + dx)
|
||||
(d/update-when :y + dy)
|
||||
(cond-> (= :bool (:type shape))
|
||||
(update :bool-content gpa/move-content move-vec))
|
||||
(cond-> (= :path (:type shape))
|
||||
(update :content gpa/move-content move-vec)))))
|
||||
|
||||
|
@ -256,6 +258,7 @@
|
|||
|
||||
(let [points' (:points shape)
|
||||
points (gco/transform-points points' transform-mtx)
|
||||
bool? (= (:type shape) :bool)
|
||||
path? (= (:type shape) :path)
|
||||
rotated? (is-rotated? points)
|
||||
|
||||
|
@ -273,6 +276,8 @@
|
|||
rotation (mod (+ base-rotation modif-rotation) 360)]
|
||||
|
||||
(-> shape
|
||||
(cond-> bool?
|
||||
(update :bool-content gpa/transform-content transform-mtx))
|
||||
(cond-> path?
|
||||
(update :content gpa/transform-content transform-mtx))
|
||||
(cond-> (not path?)
|
||||
|
|
|
@ -252,7 +252,6 @@
|
|||
(ptk/reify ::select-next-frame
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(prn "select-next-frame")
|
||||
(let [route (:route state)
|
||||
pparams (:path-params route)
|
||||
qparams (:query-params route)
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
[app.config :as cfg]
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.data.messages :as dm]
|
||||
[app.main.data.workspace.booleans :as dwb]
|
||||
[app.main.data.workspace.bool :as dwb]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.drawing :as dwd]
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
;;
|
||||
;; Copyright (c) UXBOX Labs SL
|
||||
|
||||
(ns app.main.data.workspace.booleans
|
||||
(ns app.main.data.workspace.bool
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
|
@ -38,17 +38,20 @@
|
|||
(and (contains? head :svg-attrs) (nil? (:fill-color head)))
|
||||
(assoc :fill-color clr/black))
|
||||
|
||||
head-data (select-keys head stp/style-properties)]
|
||||
[(-> {:id (uuid/next)
|
||||
:type :bool
|
||||
:bool-type bool-type
|
||||
:frame-id (:frame-id head)
|
||||
:parent-id (:parent-id head)
|
||||
:name name
|
||||
:shapes []}
|
||||
(merge head-data)
|
||||
(gsh/update-bool-selrect shapes objects))
|
||||
(cp/position-on-parent (:id head) objects)]))
|
||||
head-data (select-keys head stp/style-properties)
|
||||
|
||||
bool-shape
|
||||
(-> {:id (uuid/next)
|
||||
:type :bool
|
||||
:bool-type bool-type
|
||||
:frame-id (:frame-id head)
|
||||
:parent-id (:parent-id head)
|
||||
:name name
|
||||
:shapes (->> shapes (mapv :id))}
|
||||
(merge head-data)
|
||||
(gsh/update-bool-selrect shapes objects))]
|
||||
|
||||
[bool-shape (cp/position-on-parent (:id head) objects)]))
|
||||
|
||||
(defn group->bool
|
||||
[group bool-type objects]
|
|
@ -269,19 +269,19 @@
|
|||
:type "keyup"
|
||||
:fn #(st/emit! (dw/toggle-distances-display false))}
|
||||
|
||||
:boolean-union {:tooltip (ds/meta (ds/alt "U"))
|
||||
:bool-union {:tooltip (ds/meta (ds/alt "U"))
|
||||
:command (ds/c-mod "alt+u")
|
||||
:fn #(st/emit! (dw/create-bool :union))}
|
||||
|
||||
:boolean-difference {:tooltip (ds/meta (ds/alt "D"))
|
||||
:bool-difference {:tooltip (ds/meta (ds/alt "D"))
|
||||
:command (ds/c-mod "alt+d")
|
||||
:fn #(st/emit! (dw/create-bool :difference))}
|
||||
|
||||
:boolean-intersection {:tooltip (ds/meta (ds/alt "I"))
|
||||
:bool-intersection {:tooltip (ds/meta (ds/alt "I"))
|
||||
:command (ds/c-mod "alt+i")
|
||||
:fn #(st/emit! (dw/create-bool :intersection))}
|
||||
|
||||
:boolean-exclude {:tooltip (ds/meta (ds/alt "E"))
|
||||
:bool-exclude {:tooltip (ds/meta (ds/alt "E"))
|
||||
:command (ds/c-mod "alt+e")
|
||||
:fn #(st/emit! (dw/create-bool :exclude))}
|
||||
|
||||
|
|
|
@ -237,8 +237,7 @@
|
|||
[:& wrapper {:shape frame :view-box vbox}]]))
|
||||
|
||||
(mf/defc component-svg
|
||||
{::mf/wrap [mf/memo
|
||||
#(mf/deferred % ts/idle-then-raf)]}
|
||||
{::mf/wrap [mf/memo #(mf/deferred % ts/idle-then-raf)]}
|
||||
[{:keys [objects group zoom] :or {zoom 1} :as props}]
|
||||
(let [modifier (-> (gpt/point (:x group) (:y group))
|
||||
(gpt/negate)
|
||||
|
@ -249,17 +248,21 @@
|
|||
include-metadata? (mf/use-ctx use/include-metadata-ctx)
|
||||
|
||||
modifier-ids (concat [group-id] (cp/get-children group-id objects))
|
||||
|
||||
update-fn #(assoc-in %1 [%2 :modifiers :displacement] modifier)
|
||||
objects (reduce update-fn objects modifier-ids)
|
||||
group (assoc-in group [:modifiers :displacement] modifier)
|
||||
modifiers (reduce update-fn {} modifier-ids)
|
||||
objects (gsh/merge-modifiers objects modifiers)
|
||||
|
||||
group (get objects group-id)
|
||||
|
||||
width (* (:width group) zoom)
|
||||
height (* (:height group) zoom)
|
||||
vbox (str "0 0 " (:width group 0)
|
||||
" " (:height group 0))
|
||||
wrapper (mf/use-memo
|
||||
(mf/deps objects)
|
||||
#(group-wrapper-factory objects))]
|
||||
group-wrapper
|
||||
(mf/use-memo
|
||||
(mf/deps objects)
|
||||
#(group-wrapper-factory objects))]
|
||||
|
||||
[:svg {:view-box vbox
|
||||
:width width
|
||||
|
@ -269,7 +272,7 @@
|
|||
:xmlnsXlink "http://www.w3.org/1999/xlink"
|
||||
:xmlns:penpot (when include-metadata? "https://penpot.app/xmlns")}
|
||||
[:> shape-container {:shape group}
|
||||
[:& wrapper {:shape group :view-box vbox}]]]))
|
||||
[:& group-wrapper {:shape group :view-box vbox}]]]))
|
||||
|
||||
(mf/defc component-symbol
|
||||
[{:keys [id data] :as props}]
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
"A collection of derived refs."
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.pages :as cp]
|
||||
[app.common.path.commands :as upc]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
|
@ -246,11 +247,13 @@
|
|||
(update shape :content upc/apply-content-modifiers content-modifiers)
|
||||
shape))))
|
||||
|
||||
(defn select-children [id]
|
||||
(defn select-bool-children [id]
|
||||
(let [selector
|
||||
(fn [state]
|
||||
(let [objects (wsh/lookup-page-objects state)]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
modifiers (:workspace-modifiers state)]
|
||||
(as-> (cp/select-children id objects) $
|
||||
(gsh/merge-modifiers $ modifiers)
|
||||
(d/mapm (set-content-modifiers state) $))))]
|
||||
(l/derived selector st/state =)))
|
||||
|
||||
|
|
|
@ -29,11 +29,11 @@
|
|||
(def auto-fix (icon-xref :auto-fix))
|
||||
(def auto-height (icon-xref :auto-height))
|
||||
(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 bool-difference (icon-xref :boolean-difference))
|
||||
(def bool-exclude (icon-xref :boolean-exclude))
|
||||
(def bool-flatten (icon-xref :boolean-flatten))
|
||||
(def bool-intersection (icon-xref :boolean-intersection))
|
||||
(def bool-union (icon-xref :boolean-union))
|
||||
(def box (icon-xref :box))
|
||||
(def chain (icon-xref :chain))
|
||||
(def chat (icon-xref :chat))
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
(ns app.main.ui.shapes.bool
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.main.ui.hooks :refer [use-equal-memo]]
|
||||
[app.main.ui.shapes.export :as use]
|
||||
|
@ -26,11 +27,19 @@
|
|||
bool-content
|
||||
(mf/use-memo
|
||||
(mf/deps shape childs)
|
||||
#(or (:bool-content shape)
|
||||
(gsh/calc-bool-content shape childs)))]
|
||||
(fn []
|
||||
(cond
|
||||
(some? (:bool-content shape))
|
||||
(:bool-content shape)
|
||||
|
||||
(some? childs)
|
||||
(->> childs
|
||||
(d/mapm #(gsh/transform-shape %2))
|
||||
(gsh/calc-bool-content shape)))))]
|
||||
|
||||
[:*
|
||||
[:& path-shape {:shape (assoc shape :content bool-content)}]
|
||||
(when (some? bool-content)
|
||||
[:& path-shape {:shape (assoc shape :content bool-content)}])
|
||||
|
||||
(when include-metadata?
|
||||
[:> "penpot:bool" {}
|
||||
|
|
|
@ -57,8 +57,7 @@
|
|||
(let [{:keys [hover selected zoom]} local
|
||||
hover-shape (-> (or (first (resolve-shapes objects [hover])) frame)
|
||||
(gsh/translate-to-frame frame))
|
||||
selected-shapes (->> (resolve-shapes objects selected)
|
||||
(map #(gsh/translate-to-frame % frame)))
|
||||
selected-shapes (->> (resolve-shapes objects selected))
|
||||
|
||||
selrect (gsh/selection-rect selected-shapes)
|
||||
bounds (frame->bounds frame)]
|
||||
|
|
|
@ -250,16 +250,16 @@
|
|||
(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)
|
||||
:shortcut (sc/get-tooltip :bool-union)
|
||||
:on-click (set-bool :union)}]
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.difference")
|
||||
:shortcut (sc/get-tooltip :boolean-difference)
|
||||
:shortcut (sc/get-tooltip :bool-difference)
|
||||
:on-click (set-bool :difference)}]
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.intersection")
|
||||
:shortcut (sc/get-tooltip :boolean-intersection)
|
||||
:shortcut (sc/get-tooltip :bool-intersection)
|
||||
:on-click (set-bool :intersection)}]
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.exclude")
|
||||
:shortcut (sc/get-tooltip :boolean-exclude)
|
||||
:shortcut (sc/get-tooltip :bool-exclude)
|
||||
:on-click (set-bool :exclude)}]
|
||||
|
||||
(when (and single? is-bool? (not disable-flatten?))
|
||||
|
|
|
@ -30,15 +30,23 @@
|
|||
{::mf/wrap [#(mf/memo' % (mf/check-props ["shape"]))]
|
||||
::mf/wrap-props false}
|
||||
[props]
|
||||
(let [shape (unchecked-get props "shape")
|
||||
childs-ref (mf/use-memo
|
||||
(mf/deps (:id shape))
|
||||
#(refs/select-children (:id shape)))
|
||||
(let [shape (unchecked-get props "shape")
|
||||
child-sel-ref (mf/use-memo
|
||||
(mf/deps (:id shape))
|
||||
#(refs/is-child-selected? (:id shape)))
|
||||
|
||||
childs (mf/deref childs-ref)]
|
||||
childs-ref (mf/use-memo
|
||||
(mf/deps (:id shape))
|
||||
#(refs/select-bool-children (:id shape)))
|
||||
|
||||
child-sel? (mf/deref child-sel-ref)
|
||||
childs (mf/deref childs-ref)
|
||||
|
||||
shape (cond-> shape
|
||||
child-sel?
|
||||
(dissoc :bool-content))]
|
||||
|
||||
[:> shape-container {:shape shape}
|
||||
[:& shape-component
|
||||
{:shape shape
|
||||
:childs childs}]]))))
|
||||
[:& shape-component {:shape shape
|
||||
:childs childs}]]))))
|
||||
|
||||
|
|
|
@ -42,10 +42,10 @@
|
|||
i/mask
|
||||
i/folder))
|
||||
:bool (case (:bool-type shape)
|
||||
:difference i/boolean-difference
|
||||
:exclude i/boolean-exclude
|
||||
:intersection i/boolean-intersection
|
||||
#_:default i/boolean-union)
|
||||
:difference i/bool-difference
|
||||
:exclude i/bool-exclude
|
||||
:intersection i/bool-intersection
|
||||
#_:default i/bool-union)
|
||||
:svg-raw i/file-svg
|
||||
nil))
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
[app.main.ui.components.tab-container :refer [tab-container tab-element]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.workspace.sidebar.options.menus.align :refer [align-options]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.booleans :refer [booleans-options]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.bool :refer [bool-options]]
|
||||
[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]
|
||||
|
@ -63,7 +63,7 @@
|
|||
:title (tr "workspace.options.design")}
|
||||
[:div.element-options
|
||||
[:& align-options]
|
||||
[:& booleans-options]
|
||||
[:& bool-options]
|
||||
(case (count selected)
|
||||
0 [:& page/options]
|
||||
1 [:& shape-options {:shape (first shapes)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
;;
|
||||
;; Copyright (c) UXBOX Labs SL
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.booleans
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.bool
|
||||
(:require
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.shortcuts :as sc]
|
||||
|
@ -15,7 +15,7 @@
|
|||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(mf/defc booleans-options
|
||||
(mf/defc bool-options
|
||||
[]
|
||||
(let [selected (mf/deref refs/selected-objects)
|
||||
selected-with-children (mf/deref refs/selected-shapes-with-children)
|
||||
|
@ -52,37 +52,37 @@
|
|||
[:div.align-options
|
||||
[:div.align-group
|
||||
[:div.align-button.tooltip.tooltip-bottom
|
||||
{:alt (str (tr "workspace.shape.menu.union") " (" (sc/get-tooltip :boolean-union) ")")
|
||||
{:alt (str (tr "workspace.shape.menu.union") " (" (sc/get-tooltip :bool-union) ")")
|
||||
:class (dom/classnames :disabled disabled-bool-btns
|
||||
:selected (= head-bool-type :union))
|
||||
:on-click (set-bool :union)}
|
||||
i/boolean-union]
|
||||
i/bool-union]
|
||||
|
||||
[:div.align-button.tooltip.tooltip-bottom
|
||||
{:alt (str (tr "workspace.shape.menu.difference") " (" (sc/get-tooltip :boolean-difference) ")")
|
||||
{:alt (str (tr "workspace.shape.menu.difference") " (" (sc/get-tooltip :bool-difference) ")")
|
||||
:class (dom/classnames :disabled disabled-bool-btns
|
||||
:selected (= head-bool-type :difference))
|
||||
:on-click (set-bool :difference)}
|
||||
i/boolean-difference]
|
||||
i/bool-difference]
|
||||
|
||||
[:div.align-button.tooltip.tooltip-bottom
|
||||
{:alt (str (tr "workspace.shape.menu.intersection") " (" (sc/get-tooltip :boolean-intersection) ")")
|
||||
{:alt (str (tr "workspace.shape.menu.intersection") " (" (sc/get-tooltip :bool-intersection) ")")
|
||||
:class (dom/classnames :disabled disabled-bool-btns
|
||||
:selected (= head-bool-type :intersection))
|
||||
:on-click (set-bool :intersection)}
|
||||
i/boolean-intersection]
|
||||
i/bool-intersection]
|
||||
|
||||
[:div.align-button.tooltip.tooltip-bottom
|
||||
{:alt (str (tr "workspace.shape.menu.exclude") " (" (sc/get-tooltip :boolean-exclude) ")")
|
||||
{:alt (str (tr "workspace.shape.menu.exclude") " (" (sc/get-tooltip :bool-exclude) ")")
|
||||
:class (dom/classnames :disabled disabled-bool-btns
|
||||
:selected (= head-bool-type :exclude))
|
||||
:on-click (set-bool :exclude)}
|
||||
i/boolean-exclude]]
|
||||
i/bool-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]]]))
|
||||
i/bool-flatten]]]))
|
||||
|
Loading…
Add table
Reference in a new issue