diff --git a/CHANGES.md b/CHANGES.md index 8f785fa6a..10a3b0319 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,9 @@ - Fix auto-width for texts can make text appear stretched [Github #2482](https://github.com/penpot/penpot/issues/2482) - Fix boards name do not disappear in focus mode [#4272](https://tree.taiga.io/project/penpot/issue/4272) - Fix wrong email in the info message at change email [Taiga #4274](https://tree.taiga.io/project/penpot/issue/4274) +- Fix transform to path RMB menu item is not relevant if shape is already path [Taiga #4302](https://tree.taiga.io/project/penpot/issue/4302) +- Fix join nodes icon is active when 2 already joined nodes are selected [Taiga #4370](https://tree.taiga.io/project/penpot/issue/4370) +- Fix path nodes panel. "To curve" and "To corner" icons are active if node is already curved/cornered [Taiga #4371](https://tree.taiga.io/project/penpot/issue/4371) ## 1.16.0-beta diff --git a/common/src/app/common/pages/helpers.cljc b/common/src/app/common/pages/helpers.cljc index 02e21f8c2..a07645f30 100644 --- a/common/src/app/common/pages/helpers.cljc +++ b/common/src/app/common/pages/helpers.cljc @@ -51,6 +51,10 @@ [{:keys [type]}] (= type :svg-raw)) +(defn path-shape? + [{:keys [type]}] + (= type :path)) + (defn unframed-shape? "Checks if it's a non-frame shape in the top level." [shape] diff --git a/frontend/src/app/main/ui/workspace/context_menu.cljs b/frontend/src/app/main/ui/workspace/context_menu.cljs index a21ac8451..bdf518466 100644 --- a/frontend/src/app/main/ui/workspace/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/context_menu.cljs @@ -265,18 +265,19 @@ (mf/defc context-menu-path [{:keys [shapes disable-flatten? disable-booleans?]}] - (let [multiple? (> (count shapes) 1) - single? (= (count shapes) 1) + (let [multiple? (> (count shapes) 1) + single? (= (count shapes) 1) - has-group? (->> shapes (d/seek cph/group-shape?)) - has-bool? (->> shapes (d/seek cph/bool-shape?)) - has-frame? (->> shapes (d/seek cph/frame-shape?)) + has-group? (->> shapes (d/seek cph/group-shape?)) + has-bool? (->> shapes (d/seek cph/bool-shape?)) + has-frame? (->> shapes (d/seek cph/frame-shape?)) + has-path? (->> shapes (d/seek cph/path-shape?)) - is-group? (and single? has-group?) - is-bool? (and single? has-bool?) - is-frame? (and single? has-frame?) + is-group? (and single? has-group?) + is-bool? (and single? has-bool?) + is-frame? (and single? has-frame?) - do-start-editing (fn [] (timers/schedule #(st/emit! (dw/start-editing-selected)))) + do-start-editing (fn [] (timers/schedule #(st/emit! (dw/start-editing-selected)))) do-transform-to-path #(st/emit! (dw/convert-selected-to-path)) make-do-bool @@ -296,7 +297,7 @@ :shortcut (sc/get-tooltip :start-editing) :on-click do-start-editing}]) - (when-not (or disable-flatten? has-frame?) + (when-not (or disable-flatten? has-frame? has-path?) [:& menu-entry {:title (tr "workspace.shape.menu.transform-to-path") :on-click do-transform-to-path}]) diff --git a/frontend/src/app/main/ui/workspace/viewport/path_actions.cljs b/frontend/src/app/main/ui/workspace/viewport/path_actions.cljs index 0cf7db8a8..b66d01848 100644 --- a/frontend/src/app/main/ui/workspace/viewport/path_actions.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/path_actions.cljs @@ -17,15 +17,22 @@ (defn check-enabled [content selected-points] (let [segments (upt/get-segments content selected-points) + num-segments (count segments) num-points (count selected-points) points-selected? (seq selected-points) - segments-selected? (seq segments)] - {:make-corner points-selected? - :make-curve points-selected? + segments-selected? (seq segments) + ;; max segments for n points is (n × (n -1)) / 2 + max-segments (-> num-points + (* (- num-points 1)) + (/ 2)) + is-curve? (some #(upt/is-curve? content %) selected-points)] + + {:make-corner (and points-selected? is-curve?) + :make-curve (and points-selected? (not is-curve?)) :add-node segments-selected? :remove-node points-selected? :merge-nodes segments-selected? - :join-nodes (and points-selected? (>= num-points 2)) + :join-nodes (and points-selected? (>= num-points 2) (< num-segments max-segments)) :separate-nodes segments-selected?})) (mf/defc path-actions [{:keys [shape]}] diff --git a/frontend/src/app/util/path/tools.cljs b/frontend/src/app/util/path/tools.cljs index 2ba942815..a49cd7068 100644 --- a/frontend/src/app/util/path/tools.cljs +++ b/frontend/src/app/util/path/tools.cljs @@ -74,6 +74,13 @@ (assoc-in [:params :c2x] (:x h2)) (assoc-in [:params :c2y] (:y h2))))) +(defn is-curve? + [content point] + (let [handlers (-> (upc/content->handlers content) + (get point)) + handler-points (map #(upc/handler->point content (first %) (second %)) handlers)] + (some #(not= point %) handler-points))) + (defn make-curve-point "Changes the content to make the point a 'curve'. The handlers will be positioned in the same vector that results from te previous->next points but with fixed length." @@ -99,7 +106,6 @@ :next-p (upc/command->point next) :command cmd))))) - points (->> vectors (mapcat #(vector (:next-p %) (:prev-p %))) (remove nil?) (into #{}))] (cond @@ -124,8 +130,7 @@ next-correction (when (some? next-h) (gpt/scale (gpt/to-vec next-h point) (/ 1 3))) prev-h (when (some? prev-h) (gpt/add prev-h prev-correction)) - next-h (when (some? next-h) (gpt/add next-h next-correction)) - ] + next-h (when (some? next-h) (gpt/add next-h next-correction))] (cond-> content (and (= :line-to (:command cur-cmd)) (some? prev-p)) (update index upc/update-curve-to prev-p prev-h) @@ -147,7 +152,13 @@ (= :line-to (:command command)) (update index #(line->curve prev-p %)) + (= :curve-to (:command command)) + (update index #(line->curve prev-p %)) + (= :line-to (:command next-c)) + (update next-i #(line->curve point %)) + + (= :curve-to (:command next-c)) (update next-i #(line->curve point %))))] (->> vectors (reduce add-curve content))))))