diff --git a/common/src/app/common/types/shape/layout.cljc b/common/src/app/common/types/shape/layout.cljc index 9be46671f..a7001cd37 100644 --- a/common/src/app/common/types/shape/layout.cljc +++ b/common/src/app/common/types/shape/layout.cljc @@ -134,25 +134,41 @@ (defn wrap? [{:keys [layout-wrap-type]}] (= layout-wrap-type :wrap)) -(defn fill-width? [child] - (= :fill (:layout-item-h-sizing child))) +(defn fill-width? + ([objects id] + (= :fill (dm/get-in objects [id :layout-item-h-sizing]))) + ([child] + (= :fill (:layout-item-h-sizing child)))) -(defn fill-height? [child] - (= :fill (:layout-item-v-sizing child))) +(defn fill-height? + ([objects id] + (= :fill (dm/get-in objects [id :layout-item-v-sizing]))) + ([child] + (= :fill (:layout-item-v-sizing child)))) -(defn auto-width? [child] - (= :auto (:layout-item-h-sizing child))) +(defn auto-width? + ([objects id] + (= :auto (dm/get-in objects [id :layout-item-h-sizing]))) + ([child] + (= :auto (:layout-item-h-sizing child)))) -(defn auto-height? [child] - (= :auto (:layout-item-v-sizing child))) +(defn auto-height? + ([objects id] + (= :auto (dm/get-in objects [id :layout-item-v-sizing]))) + ([child] + (= :auto (:layout-item-v-sizing child)))) (defn col? - [{:keys [layout-flex-dir]}] - (or (= :column layout-flex-dir) (= :column-reverse layout-flex-dir))) + ([objects id] + (col? (get objects id))) + ([{:keys [layout-flex-dir]}] + (or (= :column layout-flex-dir) (= :column-reverse layout-flex-dir)))) (defn row? - [{:keys [layout-flex-dir]}] - (or (= :row layout-flex-dir) (= :row-reverse layout-flex-dir))) + ([objects id] + (row? (get objects id))) + ([{:keys [layout-flex-dir]}] + (or (= :row layout-flex-dir) (= :row-reverse layout-flex-dir)))) (defn gaps [{:keys [layout-gap]}] @@ -315,3 +331,22 @@ (defn align-self-stretch? [{:keys [layout-item-align-self]}] (= :stretch layout-item-align-self)) + +(defn change-h-sizing? + [frame-id objects children-ids] + (and (layout? objects frame-id) + (auto-width? objects frame-id) + (or (and (col? objects frame-id) + (every? (partial fill-width? objects) children-ids)) + (and (row? objects frame-id) + (some (partial fill-width? objects) children-ids))))) + +(defn change-v-sizing? + [frame-id objects children-ids] + (and (layout? objects frame-id) + (auto-height? objects frame-id) + (or (and (col? objects frame-id) + (some (partial fill-height? objects) children-ids)) + (and (row? objects frame-id) + (every? (partial fill-height? objects) children-ids))))) + diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 08c17de41..826ee7be6 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -651,20 +651,20 @@ (-> (pcb/empty-changes it page-id) (pcb/with-objects objects) - ; Move the shapes + ;; Move the shapes (pcb/change-parent parent-id shapes to-index) - ; Remove empty groups + ;; Remove empty groups (pcb/remove-objects groups-to-delete) - ; Unmask groups whose mask have moved outside + ;; Unmask groups whose mask have moved outside (pcb/update-shapes groups-to-unmask (fn [shape] (assoc shape :masked-group? false))) - ; Detach shapes moved out of their component + ;; Detach shapes moved out of their component (pcb/update-shapes shapes-to-detach (fn [shape] (assoc shape :component-id nil @@ -674,17 +674,17 @@ :shape-ref nil :touched nil))) - ; Make non root a component moved inside another one + ;; Make non root a component moved inside another one (pcb/update-shapes shapes-to-deroot (fn [shape] (assoc shape :component-root? nil))) - ; Make root a subcomponent moved outside its parent component + ;; Make root a subcomponent moved outside its parent component (pcb/update-shapes shapes-to-reroot (fn [shape] (assoc shape :component-root? true))) - ; Reset constraints depending on the new parent + ;; Reset constraints depending on the new parent (pcb/update-shapes shapes-to-unconstraint (fn [shape] (let [parent (get objects parent-id) @@ -699,7 +699,19 @@ :constraints-v (gsh/default-constraints-v moved-shape)))) {:ignore-touched true}) - ; Resize parent containers that need to + ;; Fix the sizing when moving a shape + (pcb/update-shapes parents + (fn [parent] + (if (ctl/layout? parent) + (cond-> parent + (ctl/change-h-sizing? (:id parent) objects (:shapes parent)) + (assoc :layout-item-h-sizing :fix) + + (ctl/change-v-sizing? (:id parent) objects (:shapes parent)) + (assoc :layout-item-v-sizing :fix)) + parent))) + + ;; Resize parent containers that need to (pcb/resize-parents parents)))) (defn relocate-shapes @@ -719,9 +731,9 @@ ;; If we try to move a parent into a child we remove it ids (filter #(not (cph/is-parent? objects parent-id %)) ids) - parents (if ignore-parents? - #{parent-id} - (into #{parent-id} (map #(cph/get-parent-id objects %)) ids)) + + all-parents (into #{parent-id} (map #(cph/get-parent-id objects %)) ids) + parents (if ignore-parents? #{parent-id} all-parents) groups-to-delete (loop [current-id (first parents) @@ -814,17 +826,12 @@ shapes-to-reroot shapes-to-deroot ids) - - layouts-to-update - (into #{} - (filter (partial ctl/layout? objects)) - (concat [parent-id] (cph/get-parent-ids objects parent-id))) undo-id (js/Symbol)] (rx/of (dwu/start-undo-transaction undo-id) (dch/commit-changes changes) (dwco/expand-collapse parent-id) - (ptk/data-event :layout/update layouts-to-update) + (ptk/data-event :layout/update (concat all-parents ids)) (dwu/commit-undo-transaction undo-id)))))) (defn relocate-selected-shapes diff --git a/frontend/src/app/main/data/workspace/modifiers.cljs b/frontend/src/app/main/data/workspace/modifiers.cljs index 965fa5e8b..1eaf6a688 100644 --- a/frontend/src/app/main/data/workspace/modifiers.cljs +++ b/frontend/src/app/main/data/workspace/modifiers.cljs @@ -174,42 +174,62 @@ modif-tree))) (defn build-change-frame-modifiers - [modif-tree objects selected target-frame drop-index] + [modif-tree objects selected target-frame-id drop-index] (let [origin-frame-ids (->> selected (group-by #(get-in objects [% :frame-id]))) - child-set (set (get-in objects [target-frame :shapes])) - layout? (ctl/layout? objects target-frame) + child-set (set (get-in objects [target-frame-id :shapes])) + + target-frame (get objects target-frame-id) + target-layout? (ctl/layout? target-frame) + + children-ids (concat (:shapes target-frame) selected) set-parent-ids - (fn [modif-tree shapes target-frame] + (fn [modif-tree shapes target-frame-id] (reduce (fn [modif-tree id] (update-in modif-tree [id :modifiers] #(-> % - (ctm/change-property :frame-id target-frame) - (ctm/change-property :parent-id target-frame)))) + (ctm/change-property :frame-id target-frame-id) + (ctm/change-property :parent-id target-frame-id)))) modif-tree shapes)) update-frame-modifiers (fn [modif-tree [original-frame shapes]] - (let [shapes (->> shapes (d/removev #(= target-frame %))) + (let [shapes (->> shapes (d/removev #(= target-frame-id %))) shapes (cond->> shapes - (and layout? (= original-frame target-frame)) + (and target-layout? (= original-frame target-frame-id)) ;; When movining inside a layout frame remove the shapes that are not immediate children - (filterv #(contains? child-set %)))] + (filterv #(contains? child-set %))) + children-ids (->> (dm/get-in objects [original-frame :shapes]) + (remove (set selected))) + + h-sizing? (ctl/change-h-sizing? original-frame objects children-ids) + v-sizing? (ctl/change-v-sizing? original-frame objects children-ids)] (cond-> modif-tree - (not= original-frame target-frame) + (not= original-frame target-frame-id) (-> (modifier-remove-from-parent objects shapes) - (update-in [target-frame :modifiers] ctm/add-children shapes drop-index) - (set-parent-ids shapes target-frame)) + (update-in [target-frame-id :modifiers] ctm/add-children shapes drop-index) + (set-parent-ids shapes target-frame-id) + (cond-> h-sizing? + (update-in [original-frame :modifiers] ctm/change-property :layout-item-h-sizing :fix)) + (cond-> v-sizing? + (update-in [original-frame :modifiers] ctm/change-property :layout-item-v-sizing :fix))) - (and layout? (= original-frame target-frame)) - (update-in [target-frame :modifiers] ctm/add-children shapes drop-index))))] + (and target-layout? (= original-frame target-frame-id)) + (update-in [target-frame-id :modifiers] ctm/add-children shapes drop-index))))] - (reduce update-frame-modifiers modif-tree origin-frame-ids))) + (as-> modif-tree $ + (reduce update-frame-modifiers $ origin-frame-ids) + (cond-> $ + (ctl/change-h-sizing? target-frame-id objects children-ids) + (update-in [target-frame-id :modifiers] ctm/change-property :layout-item-h-sizing :fix)) + (cond-> $ + (ctl/change-v-sizing? target-frame-id objects children-ids) + (update-in [target-frame-id :modifiers] ctm/change-property :layout-item-v-sizing :fix))))) (defn modif->js [modif-tree objects]