0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-24 07:46:13 -05:00

Add add flex layout option in context menu

This commit is contained in:
Eva 2022-11-07 18:00:26 +01:00 committed by alonso.torres
parent c1affe75e1
commit 56efb571be
9 changed files with 177 additions and 60 deletions

View file

@ -52,8 +52,8 @@
[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.shape-layout :as dwsl]
[app.main.data.workspace.shapes :as dwsh]
[app.main.data.workspace.shapes-update-layout :as dwul]
[app.main.data.workspace.state-helpers :as wsh]
[app.main.data.workspace.svg-upload :as svg]
[app.main.data.workspace.thumbnails :as dwth]
@ -690,7 +690,7 @@
(rx/of (dch/commit-changes changes)
(dwco/expand-collapse parent-id)
(dwsl/update-layout-positions [parent-id]))))))
(dwul/update-layout-positions [parent-id]))))))
(defn relocate-selected-shapes
[parent-id to-index]
@ -1571,36 +1571,6 @@
(rx/of (dch/commit-changes changes))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Artboard
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn create-artboard-from-selection
[]
(ptk/reify ::create-artboard-from-selection
ptk/WatchEvent
(watch [_ state _]
(let [objects (wsh/lookup-page-objects state)
selected (wsh/lookup-selected state)
selected-objs (map #(get objects %) selected)]
(when (d/not-empty? selected)
(let [srect (gsh/selection-rect selected-objs)
frame-id (get-in objects [(first selected) :frame-id])
parent-id (get-in objects [(first selected) :parent-id])
shape (-> (cts/make-minimal-shape :frame)
(merge {:x (:x srect) :y (:y srect) :width (:width srect) :height (:height srect)})
(assoc :frame-id frame-id :parent-id parent-id)
(cond-> (not= frame-id uuid/zero)
(assoc :fills [] :hide-in-viewer true))
(cts/setup-rect-selrect))]
(rx/of
(dwu/start-undo-transaction)
(dwsh/add-shape shape)
(dwsh/move-shapes-into-frame (:id shape) selected)
(dwu/commit-undo-transaction))))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Remove graphics
;; TODO: this should be deprecated and removed together with components-v2

View file

@ -21,7 +21,7 @@
[app.main.data.modal :as md]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.collapse :as dwc]
[app.main.data.workspace.shape-layout :as dwsl]
[app.main.data.workspace.shapes-update-layout :as dwul]
[app.main.data.workspace.state-helpers :as wsh]
[app.main.data.workspace.thumbnails :as dwt]
[app.main.data.workspace.zoom :as dwz]
@ -565,7 +565,7 @@
;; Warning: This order is important for the focus mode.
(rx/of (dch/commit-changes changes)
(select-shapes new-selected)
(dwsl/update-layout-positions frames)
(dwul/update-layout-positions frames)
(memorize-duplicated id-original id-duplicated))))))))))
(defn change-hover-state

View file

@ -8,10 +8,12 @@
(:require
[app.common.data :as d]
[app.common.pages.helpers :as cph]
[app.common.types.modifiers :as ctm]
[app.common.types.shape.layout :as ctl]
[app.common.uuid :as uuid]
[app.main.data.workspace.changes :as dwc]
[app.main.data.workspace.modifiers :as dwm]
[app.main.data.workspace.selection :as dwse]
[app.main.data.workspace.shapes :as dws]
[app.main.data.workspace.shapes-update-layout :as wsul]
[app.main.data.workspace.state-helpers :as wsh]
[beicon.core :as rx]
[potok.core :as ptk]))
@ -44,19 +46,6 @@
(def initial-grid-layout ;; TODO
{:layout :grid})
(defn update-layout-positions
[ids]
(ptk/reify ::update-layout-positions
ptk/WatchEvent
(watch [_ state _]
(let [objects (wsh/lookup-page-objects state)
ids (->> ids (filter (partial ctl/layout? objects)))]
(if (d/not-empty? ids)
(let [modif-tree (dwm/create-modif-tree ids (ctm/reflow-modifiers))]
(rx/of (dwm/set-modifiers modif-tree)
(dwm/apply-modifiers)))
(rx/empty))))))
(defn get-layout-initializer
[type]
(let [initial-layout-data (if (= type :flex) initial-flex-layout initial-grid-layout)]
@ -72,16 +61,59 @@
(let [objects (wsh/lookup-page-objects state)
children-ids (into [] (mapcat #(get-in objects [% :shapes])) ids)]
(rx/of (dwc/update-shapes ids (get-layout-initializer type))
(update-layout-positions ids)
(wsul/update-layout-positions ids)
(dwc/update-shapes children-ids #(dissoc % :constraints-h :constraints-v)))))))
(defn create-layout-from-selection
[type]
(ptk/reify ::create-layout-from-selection
ptk/WatchEvent
(watch [_ state _]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
selected (wsh/lookup-selected state)
selected-shapes (map (d/getf objects) selected)
single? (= (count selected-shapes) 1)
has-group? (->> selected-shapes (d/seek cph/group-shape?))
is-group? (and single? has-group?)]
(if is-group?
(let [parent-id (:parent-id (first selected-shapes))
new-shape-id (uuid/next)
shapes-ids (:shapes (first selected-shapes))
ordered-ids (into (d/ordered-set) shapes-ids)]
(rx/of (dwse/select-shapes ordered-ids)
(dws/create-artboard-from-selection new-shape-id parent-id)
(create-layout [new-shape-id] type)
(dws/delete-shapes page-id selected)))
(let [new-shape-id (uuid/next)]
(rx/of (dws/create-artboard-from-selection new-shape-id)
(create-layout [new-shape-id] type))))))))
(defn remove-layout
[ids]
(ptk/reify ::remove-layout
ptk/WatchEvent
(watch [_ _ _]
(rx/of (dwc/update-shapes ids #(apply dissoc % layout-keys))
(update-layout-positions ids)))))
(wsul/update-layout-positions ids)))))
(defn toogle-layout-flex
[]
(ptk/reify ::toogle-layout-flex
ptk/WatchEvent
(watch [_ state _]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
selected (wsh/lookup-selected state)
selected-shapes (map (d/getf objects) selected)
single? (= (count selected-shapes) 1)
has-flex-layout? (and single? (= :flex (:layout (first selected-shapes))))]
(if has-flex-layout?
(rx/of (remove-layout selected))
(rx/of (create-layout-from-selection :flex)))))))
(defn update-layout
[ids changes]
@ -89,7 +121,7 @@
ptk/WatchEvent
(watch [_ _ _]
(rx/of (dwc/update-shapes ids #(d/deep-merge % changes))
(update-layout-positions ids)))))
(wsul/update-layout-positions ids)))))
(defn update-layout-child
[ids changes]
@ -100,4 +132,4 @@
parent-ids (->> ids (map #(cph/get-parent-id objects %)))
layout-ids (->> ids (filter (comp ctl/layout? (d/getf objects))))]
(rx/of (dwc/update-shapes ids #(d/deep-merge (or % {}) changes))
(update-layout-positions (d/concat-vec layout-ids parent-ids)))))))
(wsul/update-layout-positions (d/concat-vec layout-ids parent-ids)))))))

View file

@ -9,6 +9,7 @@
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.geom.proportions :as gpr]
[app.common.geom.shapes :as gsh]
[app.common.pages.changes-builder :as pcb]
[app.common.pages.helpers :as cph]
[app.common.spec :as us]
@ -22,8 +23,9 @@
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.edition :as dwe]
[app.main.data.workspace.selection :as dws]
[app.main.data.workspace.shape-layout :as dwsl]
[app.main.data.workspace.shapes-update-layout :as dwsul]
[app.main.data.workspace.state-helpers :as wsh]
[app.main.data.workspace.undo :as dwu]
[app.main.features :as features]
[app.main.streams :as ms]
[beicon.core :as rx]
@ -102,7 +104,7 @@
(rx/concat
(rx/of (dch/commit-changes changes)
(dwsl/update-layout-positions [(:parent-id shape)])
(dwsul/update-layout-positions [(:parent-id shape)])
(when-not no-select?
(dws/select-shapes (d/ordered-set id))))
(when (= :text (:type attrs))
@ -270,9 +272,9 @@
(reduce ctp/remove-flow flows))))))]
(rx/of (dc/detach-comment-thread ids)
(dwsl/update-layout-positions all-parents)
(dwsul/update-layout-positions all-parents)
(dch/commit-changes changes)
(dwsl/update-layout-positions layout-ids)))))))
(dwsul/update-layout-positions layout-ids)))))))
(defn- viewport-center
[state]
@ -298,3 +300,37 @@
(assoc :frame-id frame-id)
(cts/setup-rect-selrect))]
(rx/of (add-shape shape))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Artboard
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn create-artboard-from-selection
([]
(create-artboard-from-selection nil))
([id]
(create-artboard-from-selection id nil))
([id parent-id]
(ptk/reify ::create-artboard-from-selection
ptk/WatchEvent
(watch [_ state _]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
selected (wsh/lookup-selected state)
selected-objs (map #(get objects %) selected)]
(when (d/not-empty? selected)
(let [srect (gsh/selection-rect selected-objs)
frame-id (get-in objects [(first selected) :frame-id])
parent-id (or parent-id (get-in objects [(first selected) :parent-id]))
shape (-> (cts/make-minimal-shape :frame)
(merge {:x (:x srect) :y (:y srect) :width (:width srect) :height (:height srect)})
(cond-> id
(assoc :id id))
(assoc :frame-id frame-id :parent-id parent-id)
(cond-> (not= frame-id uuid/zero)
(assoc :fills [] :hide-in-viewer true))
(cts/setup-rect-selrect))]
(rx/of
(dwu/start-undo-transaction)
(add-shape shape)
(move-shapes-into-frame (:id shape) selected)
(dwu/commit-undo-transaction)))))))))

View file

@ -0,0 +1,28 @@
;; 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/.
;;
;; Copyright (c) KALEIDOS INC
(ns app.main.data.workspace.shapes-update-layout
(:require
[app.common.data :as d]
[app.common.types.modifiers :as ctm]
[app.common.types.shape.layout :as ctl]
[app.main.data.workspace.modifiers :as dwm]
[app.main.data.workspace.state-helpers :as wsh]
[beicon.core :as rx]
[potok.core :as ptk]))
(defn update-layout-positions
[ids]
(ptk/reify ::update-layout-positions
ptk/WatchEvent
(watch [_ state _]
(let [objects (wsh/lookup-page-objects state)
ids (->> ids (filter (partial ctl/layout? objects)))]
(if (d/not-empty? ids)
(let [modif-tree (dwm/create-modif-tree ids (ctm/reflow-modifiers))]
(rx/of (dwm/set-modifiers modif-tree)
(dwm/apply-modifiers)))
(rx/empty))))))

View file

@ -15,6 +15,8 @@
[app.main.data.workspace.drawing :as dwd]
[app.main.data.workspace.layers :as dwly]
[app.main.data.workspace.libraries :as dwl]
[app.main.data.workspace.shape-layout :as dwsl]
[app.main.data.workspace.shapes :as dws]
[app.main.data.workspace.texts :as dwtxt]
[app.main.data.workspace.transforms :as dwt]
[app.main.data.workspace.undo :as dwu]
@ -204,7 +206,12 @@
:artboard-selection {:tooltip (ds/meta (ds/alt "G"))
:command (ds/c-mod "alt+g")
:subsections [:modify-layers]
:fn #(st/emit! (dw/create-artboard-from-selection))}
:fn #(st/emit! (dws/create-artboard-from-selection))}
:toogle-layout-flex {:tooltip (ds/shift "F")
:command "shift+f"
:subsections [:modify-layers]
:fn #(st/emit! (dwsl/toogle-layout-flex))}
;; TOOLS
@ -382,7 +389,7 @@
:show-shortcuts {:tooltip "?"
:command "?"
:subsections [:main-menu]
:fn #(st/emit! (toggle-layout-flag :shortcuts)) }
:fn #(st/emit! (toggle-layout-flag :shortcuts))}
;; PANELS

View file

@ -19,6 +19,8 @@
[app.main.data.workspace.interactions :as dwi]
[app.main.data.workspace.libraries :as dwl]
[app.main.data.workspace.selection :as dws]
[app.main.data.workspace.shape-layout :as dwsl]
[app.main.data.workspace.shapes :as dwsh]
[app.main.data.workspace.shortcuts :as sc]
[app.main.features :as features]
[app.main.refs :as refs]
@ -212,7 +214,7 @@
(let [multiple? (> (count shapes) 1)
single? (= (count shapes) 1)
do-create-artboard-from-selection #(st/emit! (dw/create-artboard-from-selection))
do-create-artboard-from-selection #(st/emit! (dwsh/create-artboard-from-selection))
has-frame? (->> shapes (d/seek cph/frame-shape?))
has-group? (->> shapes (d/seek cph/group-shape?))
@ -364,6 +366,31 @@
[:& menu-entry {:title (tr "workspace.shape.menu.flow-start")
:on-click do-add-flow}])))))
(mf/defc context-menu-flex
[{:keys [shapes]}]
(let [single? (= (count shapes) 1)
has-frame? (->> shapes (d/seek cph/frame-shape?))
is-frame? (and single? has-frame?)
is-flex-container? (and is-frame? (= :flex (:layout (first shapes))))
has-group? (->> shapes (d/seek cph/group-shape?))
is-group? (and single? has-group?)
ids (->> shapes (map :id))
add-flex #(st/emit! (dwsl/create-layout-from-selection :flex))
remove-flex #(st/emit! (dwsl/remove-layout ids))]
(cond
(or (not single?) (and is-frame? (not is-flex-container?)) is-group?)
[:*
[:& menu-separator]
[:& menu-entry {:title (tr "workspace.shape.menu.add-flex")
:shortcut (sc/get-tooltip :toogle-layout-flex)
:on-click add-flex}]]
is-flex-container?
[:*
[:& menu-separator]
[:& menu-entry {:title (tr "workspace.shape.menu.remove-flex")
:shortcut (sc/get-tooltip :toogle-layout-flex)
:on-click remove-flex}]])))
(mf/defc context-menu-component
[{:keys [shapes]}]
@ -517,6 +544,7 @@
[:> context-menu-path props]
[:> context-menu-layer-options props]
[:> context-menu-prototype props]
[:> context-menu-flex props]
[:> context-menu-component props]
[:> context-menu-delete props]])))

View file

@ -4077,6 +4077,14 @@ msgstr "Update main components"
msgid "workspace.shape.menu.update-main"
msgstr "Update main component"
#: src/app/main/ui/workspace/context_menu.cljs
msgid "workspace.shape.menu.add-flex"
msgstr "Add layout flex"
#: src/app/main/ui/workspace/context_menu.cljs
msgid "workspace.shape.menu.remove-flex"
msgstr "Remove layout flex"
msgid "workspace.sidebar.collapse"
msgstr "Collapse sidebar"

View file

@ -4518,6 +4518,14 @@ msgstr "Actualizar componentes"
msgid "workspace.shape.menu.update-main"
msgstr "Actualizar componente principal"
#: src/app/main/ui/workspace/context_menu.cljs
msgid "workspace.shape.menu.add-flex"
msgstr "Añadir layout flex"
#: src/app/main/ui/workspace/context_menu.cljs
msgid "workspace.shape.menu.remove-flex"
msgstr "Eliminar layout flex"
msgid "workspace.sidebar.collapse"
msgstr "Cerrar barra lateral"