mirror of
https://github.com/penpot/penpot.git
synced 2025-03-24 13:41:39 -05:00
✨ Reduce handlers for the flex layout gaps and paddings
This commit is contained in:
parent
843a3f7f6e
commit
e193261d7f
9 changed files with 808 additions and 643 deletions
|
@ -20,6 +20,7 @@
|
|||
|
||||
- Select through stroke only rectangle [Taiga #5484](https://tree.taiga.io/project/penpot/issue/5484)
|
||||
- Override browser Ctrl+ and Ctrl- zoom with Penpot Zoom [Taiga #3200](https://tree.taiga.io/project/penpot/us/3200)
|
||||
- Reduce handlers for the flex layout gaps and paddings
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
|
|
16
frontend/src/app/main/ui/flex_controls.cljs
Normal file
16
frontend/src/app/main/ui/flex_controls.cljs
Normal file
|
@ -0,0 +1,16 @@
|
|||
;; 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.ui.flex-controls
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.ui.flex-controls.gap :as fcg]
|
||||
[app.main.ui.flex-controls.margin :as fcm]
|
||||
[app.main.ui.flex-controls.padding :as fcp]))
|
||||
|
||||
(dm/export fcg/gap-control)
|
||||
(dm/export fcm/margin-control)
|
||||
(dm/export fcp/padding-control)
|
35
frontend/src/app/main/ui/flex_controls/common.cljs
Normal file
35
frontend/src/app/main/ui/flex_controls/common.cljs
Normal file
|
@ -0,0 +1,35 @@
|
|||
(ns app.main.ui.flex-controls.common
|
||||
(:require
|
||||
[app.main.ui.formats :as fmt]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
;; ------------------------------------------------
|
||||
;; CONSTANTS
|
||||
;; ------------------------------------------------
|
||||
|
||||
(def font-size 11)
|
||||
(def distance-color "var(--color-distance)")
|
||||
(def distance-text-color "var(--color-white)")
|
||||
(def warning-color "var(--color-warning)")
|
||||
(def flex-display-pill-width 40)
|
||||
(def flex-display-pill-height 20)
|
||||
(def flex-display-pill-border-radius 4)
|
||||
|
||||
(mf/defc flex-display-pill
|
||||
[{:keys [x y width height font-size border-radius value color]}]
|
||||
[:g.distance-pill
|
||||
[:rect {:x x
|
||||
:y y
|
||||
:width width
|
||||
:height height
|
||||
:rx border-radius
|
||||
:ry border-radius
|
||||
:style {:fill color}}]
|
||||
|
||||
[:text {:x (+ x (/ width 2))
|
||||
:y (+ y (/ height 2))
|
||||
:text-anchor "middle"
|
||||
:dominant-baseline "central"
|
||||
:style {:fill distance-text-color
|
||||
:font-size font-size}}
|
||||
(fmt/format-number (or value 0))]])
|
311
frontend/src/app/main/ui/flex_controls/gap.cljs
Normal file
311
frontend/src/app/main/ui/flex_controls/gap.cljs
Normal file
|
@ -0,0 +1,311 @@
|
|||
;; 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.ui.flex-controls.gap
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.geom.shapes.flex-layout :as gsl]
|
||||
[app.common.geom.shapes.points :as gpo]
|
||||
[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]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.css-cursors :as cur]
|
||||
[app.main.ui.flex-controls.common :as fcc]
|
||||
[app.main.ui.workspace.viewport.viewport-ref :refer [point->viewport]]
|
||||
[app.util.dom :as dom]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc gap-display
|
||||
[{:keys [frame-id zoom gap-type gap on-pointer-enter on-pointer-leave
|
||||
rect-data hover? selected? mouse-pos hover-value
|
||||
on-move-selected on-context-menu]}]
|
||||
(let [resizing (mf/use-var nil)
|
||||
start (mf/use-var nil)
|
||||
original-value (mf/use-var 0)
|
||||
negate? (:resize-negate? rect-data)
|
||||
axis (:resize-axis rect-data)
|
||||
|
||||
on-pointer-down
|
||||
(mf/use-fn
|
||||
(mf/deps frame-id gap-type gap)
|
||||
(fn [event]
|
||||
(dom/capture-pointer event)
|
||||
(reset! resizing gap-type)
|
||||
(reset! start (dom/get-client-position event))
|
||||
(reset! original-value (:initial-value rect-data))))
|
||||
|
||||
on-lost-pointer-capture
|
||||
(mf/use-fn
|
||||
(mf/deps frame-id gap-type gap)
|
||||
(fn [event]
|
||||
(dom/release-pointer event)
|
||||
(reset! resizing nil)
|
||||
(reset! start nil)
|
||||
(reset! original-value 0)
|
||||
(st/emit! (dwm/apply-modifiers))))
|
||||
|
||||
on-pointer-move
|
||||
(mf/use-fn
|
||||
(mf/deps frame-id gap-type gap)
|
||||
(fn [event]
|
||||
(let [pos (dom/get-client-position event)]
|
||||
(reset! mouse-pos (point->viewport pos))
|
||||
(when (= @resizing gap-type)
|
||||
(let [delta (-> (gpt/to-vec @start pos)
|
||||
(cond-> negate? gpt/negate)
|
||||
(get axis))
|
||||
val (int (max (+ @original-value (/ delta zoom)) 0))
|
||||
layout-gap (assoc gap gap-type val)
|
||||
modifiers (dwm/create-modif-tree [frame-id] (ctm/change-property (ctm/empty) :layout-gap layout-gap))]
|
||||
|
||||
(reset! hover-value val)
|
||||
(st/emit! (dwm/set-modifiers modifiers)))))))]
|
||||
|
||||
[:g.gap-rect
|
||||
[:rect.info-area
|
||||
{:x (:x rect-data)
|
||||
:y (:y rect-data)
|
||||
:width (:width rect-data)
|
||||
:height (:height rect-data)
|
||||
:on-pointer-enter on-pointer-enter
|
||||
:on-pointer-leave on-pointer-leave
|
||||
:on-pointer-move on-pointer-move
|
||||
:on-pointer-down on-move-selected
|
||||
:on-context-menu on-context-menu
|
||||
|
||||
:style {:fill (if (or hover? selected?) fcc/distance-color "none")
|
||||
:opacity (if selected? 0.5 0.25)}}]
|
||||
|
||||
(let [handle-width
|
||||
(if (= axis :x)
|
||||
(/ 2 zoom)
|
||||
(min (* (:width rect-data) 0.5) (/ 20 zoom)))
|
||||
|
||||
handle-height
|
||||
(if (= axis :y)
|
||||
(/ 2 zoom)
|
||||
(min (* (:height rect-data) 0.5) (/ 30 zoom)))]
|
||||
[:rect.handle
|
||||
{:x (+ (:x rect-data) (/ (- (:width rect-data) handle-width) 2))
|
||||
:y (+ (:y rect-data) (/ (- (:height rect-data) handle-height) 2))
|
||||
:width handle-width
|
||||
:height handle-height
|
||||
:on-pointer-enter on-pointer-enter
|
||||
:on-pointer-leave on-pointer-leave
|
||||
:on-pointer-down on-pointer-down
|
||||
:on-lost-pointer-capture on-lost-pointer-capture
|
||||
:on-pointer-move on-pointer-move
|
||||
:on-context-menu on-context-menu
|
||||
:class (when (or hover? selected?)
|
||||
(if (= (:resize-axis rect-data) :x) (cur/get-dynamic "resize-ew" 0) (cur/get-dynamic "resize-ew" 90)))
|
||||
:style {:fill (if (or hover? selected?) fcc/distance-color "none")
|
||||
:opacity (if selected? 0 1)}}])]))
|
||||
|
||||
(mf/defc gap-rects
|
||||
[{:keys [frame zoom on-move-selected on-context-menu]}]
|
||||
(let [frame-id (:id frame)
|
||||
saved-dir (:layout-flex-dir frame)
|
||||
is-col? (or (= :column saved-dir) (= :column-reverse saved-dir))
|
||||
flip-x (:flip-x frame)
|
||||
flip-y (:flip-y frame)
|
||||
pill-width (/ fcc/flex-display-pill-width zoom)
|
||||
pill-height (/ fcc/flex-display-pill-height zoom)
|
||||
workspace-modifiers (mf/deref refs/workspace-modifiers)
|
||||
gap-selected (mf/deref refs/workspace-gap-selected)
|
||||
hover (mf/use-var nil)
|
||||
hover-value (mf/use-var 0)
|
||||
mouse-pos (mf/use-var nil)
|
||||
padding (:layout-padding frame)
|
||||
gap (:layout-gap frame)
|
||||
{:keys [width height x1 y1]} (:selrect frame)
|
||||
on-pointer-enter (fn [hover-type val]
|
||||
(reset! hover hover-type)
|
||||
(reset! hover-value val))
|
||||
|
||||
on-pointer-leave #(reset! hover nil)
|
||||
negate {:column-gap (if flip-x true false)
|
||||
:row-gap (if flip-y true false)}
|
||||
|
||||
objects (wsh/lookup-page-objects @st/state)
|
||||
children (->> (cfh/get-immediate-children objects frame-id)
|
||||
(remove ctl/position-absolute?))
|
||||
|
||||
children-to-display (if (or (= :row-reverse saved-dir)
|
||||
(= :column-reverse saved-dir))
|
||||
(drop-last children)
|
||||
(rest children))
|
||||
children-to-display (->> children-to-display
|
||||
(map #(gsh/transform-shape % (get-in workspace-modifiers [(:id %) :modifiers]))))
|
||||
|
||||
wrap-blocks
|
||||
(let [block-children (->> children
|
||||
(map #(vector (gpo/parent-coords-bounds (:points %) (:points frame)) %)))
|
||||
bounds (d/lazy-map (keys objects) #(gsh/shape->points (get objects %)))
|
||||
|
||||
layout-data (gsl/calc-layout-data frame (:points frame) block-children bounds objects)
|
||||
layout-bounds (:layout-bounds layout-data)
|
||||
xv #(gpo/start-hv layout-bounds %)
|
||||
yv #(gpo/start-vv layout-bounds %)]
|
||||
(for [{:keys [start-p line-width line-height layout-gap-row layout-gap-col num-children]} (:layout-lines layout-data)]
|
||||
(let [line-width (if is-col? line-width (+ line-width (* (dec num-children) layout-gap-row)))
|
||||
line-height (if is-col? (+ line-height (* (dec num-children) layout-gap-col)) line-height)
|
||||
end-p (-> start-p (gpt/add (xv line-width)) (gpt/add (yv line-height)))]
|
||||
{:x1 (min (:x start-p) (:x end-p))
|
||||
:y1 (min (:y start-p) (:y end-p))
|
||||
:x2 (max (:x start-p) (:x end-p))
|
||||
:y2 (max (:y start-p) (:y end-p))})))
|
||||
|
||||
block-contains
|
||||
(fn [x y block]
|
||||
(if is-col?
|
||||
(<= (:x1 block) x (:x2 block))
|
||||
(<= (:y1 block) y (:y2 block))))
|
||||
|
||||
get-container-block
|
||||
(fn [shape]
|
||||
(let [selrect (:selrect shape)
|
||||
x (/ (+ (:x1 selrect) (:x2 selrect)) 2)
|
||||
y (/ (+ (:y1 selrect) (:y2 selrect)) 2)]
|
||||
(->> wrap-blocks
|
||||
(filter #(block-contains x y %))
|
||||
first)))
|
||||
|
||||
create-cgdd
|
||||
(fn [shape]
|
||||
(let [block (get-container-block shape)
|
||||
x (if flip-x
|
||||
(- (:x1 (:selrect shape))
|
||||
(get-in shape [:layout-item-margin :m2])
|
||||
(:column-gap gap))
|
||||
(+ (:x2 (:selrect shape)) (get-in shape [:layout-item-margin :m2])))
|
||||
y (:y1 block)
|
||||
h (- (:y2 block) (:y1 block))]
|
||||
{:x x
|
||||
:y y
|
||||
:height h
|
||||
:width (:column-gap gap)
|
||||
:initial-value (:column-gap gap)
|
||||
:resize-type :left
|
||||
:resize-axis :x
|
||||
:resize-negate? (:column-gap negate)
|
||||
:gap-type (if is-col? :row-gap :column-gap)}))
|
||||
|
||||
create-cgdd-block
|
||||
(fn [block]
|
||||
(let [x (if flip-x
|
||||
(- (:x1 block) (:column-gap gap))
|
||||
(:x2 block))
|
||||
y (if flip-y
|
||||
(+ y1 (:p3 padding))
|
||||
(+ y1 (:p1 padding)))
|
||||
h (- height (+ (:p1 padding) (:p3 padding)))]
|
||||
{:x x
|
||||
:y y
|
||||
:width (:column-gap gap)
|
||||
:height h
|
||||
:initial-value (:column-gap gap)
|
||||
:resize-type :left
|
||||
:resize-axis :x
|
||||
:resize-negate? (:column-gap negate)
|
||||
:gap-type (if is-col? :column-gap :row-gap)}))
|
||||
|
||||
create-rgdd
|
||||
(fn [shape]
|
||||
(let [block (get-container-block shape)
|
||||
x (:x1 block)
|
||||
y (if flip-y
|
||||
(- (:y1 (:selrect shape))
|
||||
(get-in shape [:layout-item-margin :m3])
|
||||
(:row-gap gap))
|
||||
(+ (:y2 (:selrect shape)) (get-in shape [:layout-item-margin :m3])))
|
||||
w (- (:x2 block) (:x1 block))]
|
||||
{:x x
|
||||
:y y
|
||||
:width w
|
||||
:height (:row-gap gap)
|
||||
:initial-value (:row-gap gap)
|
||||
:resize-type :bottom
|
||||
:resize-axis :y
|
||||
:resize-negate? (:row-gap negate)
|
||||
:gap-type (if is-col? :row-gap :column-gap)}))
|
||||
|
||||
create-rgdd-block
|
||||
(fn [block]
|
||||
(let [x (if flip-x
|
||||
(+ x1 (:p2 padding))
|
||||
(+ x1 (:p4 padding)))
|
||||
y (if flip-y
|
||||
(- (:y1 block) (:row-gap gap))
|
||||
(:y2 block))
|
||||
w (- width (+ (:p2 padding) (:p4 padding)))]
|
||||
{:x x
|
||||
:y y
|
||||
:width w
|
||||
:height (:row-gap gap)
|
||||
:initial-value (:row-gap gap)
|
||||
:resize-type :bottom
|
||||
:resize-axis :y
|
||||
:resize-negate? (:row-gap negate)
|
||||
:gap-type (if is-col? :column-gap :row-gap)}))
|
||||
|
||||
display-blocks (if is-col?
|
||||
(->> (drop-last wrap-blocks)
|
||||
(map create-cgdd-block))
|
||||
(->> (drop-last wrap-blocks)
|
||||
(map create-rgdd-block)))
|
||||
|
||||
display-children (if is-col?
|
||||
(->> children-to-display
|
||||
(map create-rgdd))
|
||||
(->> children-to-display
|
||||
(map create-cgdd)))]
|
||||
|
||||
[:g.gaps {:pointer-events "visible"}
|
||||
(for [[index display-item] (d/enumerate (concat display-blocks display-children))]
|
||||
(let [gap-type (:gap-type display-item)]
|
||||
[:& gap-display {:key (str frame-id index)
|
||||
:frame-id frame-id
|
||||
:zoom zoom
|
||||
:gap-type gap-type
|
||||
:gap gap
|
||||
:on-pointer-enter (partial on-pointer-enter gap-type (get gap gap-type))
|
||||
:on-pointer-leave on-pointer-leave
|
||||
:on-move-selected on-move-selected
|
||||
:on-context-menu on-context-menu
|
||||
:rect-data display-item
|
||||
:hover? (= @hover gap-type)
|
||||
:selected? (= gap-selected gap-type)
|
||||
:mouse-pos mouse-pos
|
||||
:hover-value hover-value}]))
|
||||
|
||||
(when @hover
|
||||
[:& fcc/flex-display-pill
|
||||
{:height pill-height
|
||||
:width pill-width
|
||||
:font-size (/ fcc/font-size zoom)
|
||||
:border-radius (/ fcc/flex-display-pill-border-radius zoom)
|
||||
:color fcc/distance-color
|
||||
:x (:x @mouse-pos)
|
||||
:y (- (:y @mouse-pos) pill-width)
|
||||
:value @hover-value}])]))
|
||||
|
||||
|
||||
(mf/defc gap-control
|
||||
[{:keys [frame zoom on-move-selected on-context-menu]}]
|
||||
(when frame
|
||||
[:g.measurement-gaps {:pointer-events "none"}
|
||||
[:g.hover-shapes
|
||||
[:& gap-rects
|
||||
{:frame frame
|
||||
:zoom zoom
|
||||
:on-move-selected on-move-selected
|
||||
:on-context-menu on-context-menu}]]]))
|
185
frontend/src/app/main/ui/flex_controls/margin.cljs
Normal file
185
frontend/src/app/main/ui/flex_controls/margin.cljs
Normal file
|
@ -0,0 +1,185 @@
|
|||
;; 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.ui.flex-controls.margin
|
||||
(:require
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[app.main.data.workspace.modifiers :as dwm]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.css-cursors :as cur]
|
||||
[app.main.ui.flex-controls.common :as fcc]
|
||||
[app.main.ui.workspace.viewport.viewport-ref :refer [point->viewport]]
|
||||
[app.util.dom :as dom]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc margin-display [{:keys [shape-id zoom hover-all? hover-v? hover-h? margin-num margin on-pointer-enter on-pointer-leave
|
||||
rect-data hover? selected? mouse-pos hover-value]}]
|
||||
(let [resizing? (mf/use-var false)
|
||||
start (mf/use-var nil)
|
||||
original-value (mf/use-var 0)
|
||||
negate? (true? (:resize-negate? rect-data))
|
||||
axis (:resize-axis rect-data)
|
||||
|
||||
on-pointer-down
|
||||
(mf/use-fn
|
||||
(mf/deps shape-id margin-num margin)
|
||||
(fn [event]
|
||||
(dom/capture-pointer event)
|
||||
(reset! resizing? true)
|
||||
(reset! start (dom/get-client-position event))
|
||||
(reset! original-value (:initial-value rect-data))))
|
||||
|
||||
on-lost-pointer-capture
|
||||
(mf/use-fn
|
||||
(mf/deps shape-id margin-num margin)
|
||||
(fn [event]
|
||||
(dom/release-pointer event)
|
||||
(reset! resizing? false)
|
||||
(reset! start nil)
|
||||
(reset! original-value 0)
|
||||
(st/emit! (dwm/apply-modifiers))))
|
||||
|
||||
on-pointer-move
|
||||
(mf/use-fn
|
||||
(mf/deps shape-id margin-num margin hover-all? hover-v? hover-h?)
|
||||
(fn [event]
|
||||
(let [pos (dom/get-client-position event)]
|
||||
(reset! mouse-pos (point->viewport pos))
|
||||
(when @resizing?
|
||||
(let [delta (-> (gpt/to-vec @start pos)
|
||||
(cond-> negate? gpt/negate)
|
||||
(get axis))
|
||||
val (int (max (+ @original-value (/ delta zoom)) 0))
|
||||
layout-item-margin (cond
|
||||
hover-all? (assoc margin :m1 val :m2 val :m3 val :m4 val)
|
||||
hover-v? (assoc margin :m1 val :m3 val)
|
||||
hover-h? (assoc margin :m2 val :m4 val)
|
||||
:else (assoc margin margin-num val))
|
||||
layout-item-margin-type (if (= (:m1 margin) (:m2 margin) (:m3 margin) (:m4 margin)) :simple :multiple)
|
||||
modifiers (dwm/create-modif-tree [shape-id]
|
||||
(-> (ctm/empty)
|
||||
(ctm/change-property :layout-item-margin layout-item-margin)
|
||||
(ctm/change-property :layout-item-margin-type layout-item-margin-type)))]
|
||||
(reset! hover-value val)
|
||||
(st/emit! (dwm/set-modifiers modifiers)))))))]
|
||||
|
||||
[:rect.margin-rect
|
||||
{:x (:x rect-data)
|
||||
:y (:y rect-data)
|
||||
:width (:width rect-data)
|
||||
:height (:height rect-data)
|
||||
:on-pointer-enter on-pointer-enter
|
||||
:on-pointer-leave on-pointer-leave
|
||||
:on-pointer-down on-pointer-down
|
||||
:on-lost-pointer-capture on-lost-pointer-capture
|
||||
:on-pointer-move on-pointer-move
|
||||
:class (when (or hover? selected?)
|
||||
(if (= (:resize-axis rect-data) :x) (cur/get-dynamic "resize-ew" 0) (cur/get-dynamic "resize-ew" 90)))
|
||||
:style {:fill (if (or hover? selected?) fcc/warning-color "none")
|
||||
:opacity (if selected? 0.5 0.25)}}]))
|
||||
|
||||
|
||||
(mf/defc margin-rects [{:keys [shape frame zoom alt? shift?]}]
|
||||
(let [shape-id (:id shape)
|
||||
pill-width (/ fcc/flex-display-pill-width zoom)
|
||||
pill-height (/ fcc/flex-display-pill-height zoom)
|
||||
margins-selected (mf/deref refs/workspace-margins-selected)
|
||||
hover-value (mf/use-var 0)
|
||||
mouse-pos (mf/use-var nil)
|
||||
hover (mf/use-var nil)
|
||||
hover-all? (and (not (nil? @hover)) alt?)
|
||||
hover-v? (and (or (= @hover :m1) (= @hover :m3)) shift?)
|
||||
hover-h? (and (or (= @hover :m2) (= @hover :m4)) shift?)
|
||||
margin (:layout-item-margin shape)
|
||||
{:keys [width height x1 x2 y1 y2]} (:selrect shape)
|
||||
on-pointer-enter (fn [hover-type val]
|
||||
(reset! hover hover-type)
|
||||
(reset! hover-value val))
|
||||
on-pointer-leave #(reset! hover nil)
|
||||
hover? #(or hover-all?
|
||||
(and (or (= % :m1) (= % :m3)) hover-v?)
|
||||
(and (or (= % :m2) (= % :m4)) hover-h?)
|
||||
(= @hover %))
|
||||
margin-display-data {:m1 {:key (str shape-id "-m1")
|
||||
:x x1
|
||||
:y (if (:flip-y frame) y2 (- y1 (:m1 margin)))
|
||||
:width width
|
||||
:height (:m1 margin)
|
||||
:initial-value (:m1 margin)
|
||||
:resize-type :top
|
||||
:resize-axis :y
|
||||
:resize-negate? (:flip-y frame)}
|
||||
:m2 {:key (str shape-id "-m2")
|
||||
:x (if (:flip-x frame) (- x1 (:m2 margin)) x2)
|
||||
:y y1
|
||||
:width (:m2 margin)
|
||||
:height height
|
||||
:initial-value (:m2 margin)
|
||||
:resize-type :left
|
||||
:resize-axis :x
|
||||
:resize-negate? (:flip-x frame)}
|
||||
:m3 {:key (str shape-id "-m3")
|
||||
:x x1
|
||||
:y (if (:flip-y frame) (- y1 (:m3 margin)) y2)
|
||||
:width width
|
||||
:height (:m3 margin)
|
||||
:initial-value (:m3 margin)
|
||||
:resize-type :top
|
||||
:resize-axis :y
|
||||
:resize-negate? (:flip-y frame)}
|
||||
:m4 {:key (str shape-id "-m4")
|
||||
:x (if (:flip-x frame) x2 (- x1 (:m4 margin)))
|
||||
:y y1
|
||||
:width (:m4 margin)
|
||||
:height height
|
||||
:initial-value (:m4 margin)
|
||||
:resize-type :left
|
||||
:resize-axis :x
|
||||
:resize-negate? (:flip-x frame)}}]
|
||||
|
||||
[:g.margins {:pointer-events "visible"}
|
||||
(for [[margin-num rect-data] margin-display-data]
|
||||
[:& margin-display
|
||||
{:key (:key rect-data)
|
||||
:shape-id shape-id
|
||||
:zoom zoom
|
||||
:hover-all? hover-all?
|
||||
:hover-v? hover-v?
|
||||
:hover-h? hover-h?
|
||||
:margin-num margin-num
|
||||
:margin margin
|
||||
:on-pointer-enter (partial on-pointer-enter margin-num (get margin margin-num))
|
||||
:on-pointer-leave on-pointer-leave
|
||||
:rect-data rect-data
|
||||
:hover? (hover? margin-num)
|
||||
:selected? (get margins-selected margin-num)
|
||||
:mouse-pos mouse-pos
|
||||
:hover-value hover-value}])
|
||||
|
||||
(when @hover
|
||||
[:& fcc/flex-display-pill
|
||||
{:height pill-height
|
||||
:width pill-width
|
||||
:font-size (/ fcc/font-size zoom)
|
||||
:border-radius (/ fcc/flex-display-pill-border-radius zoom)
|
||||
:color fcc/warning-color
|
||||
:x (:x @mouse-pos)
|
||||
:y (- (:y @mouse-pos) pill-width)
|
||||
:value @hover-value}])]))
|
||||
|
||||
(mf/defc margin-control
|
||||
[{:keys [shape parent zoom alt? shift?]}]
|
||||
(when shape
|
||||
[:g.measurement-gaps {:pointer-events "none"}
|
||||
[:g.hover-shapes
|
||||
[:& margin-rects
|
||||
{:shape shape
|
||||
:frame parent
|
||||
:zoom zoom
|
||||
:alt? alt?
|
||||
:shift? shift?}]]]))
|
223
frontend/src/app/main/ui/flex_controls/padding.cljs
Normal file
223
frontend/src/app/main/ui/flex_controls/padding.cljs
Normal file
|
@ -0,0 +1,223 @@
|
|||
;; 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.ui.flex-controls.padding
|
||||
(:require
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[app.main.data.workspace.modifiers :as dwm]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.css-cursors :as cur]
|
||||
[app.main.ui.flex-controls.common :as fcc]
|
||||
[app.main.ui.workspace.viewport.viewport-ref :refer [point->viewport]]
|
||||
[app.util.dom :as dom]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc padding-display
|
||||
[{:keys [frame-id zoom hover-all? hover-v? hover-h? padding-num padding on-pointer-enter on-pointer-leave
|
||||
rect-data hover? selected? mouse-pos hover-value on-move-selected on-context-menu]}]
|
||||
(let [resizing? (mf/use-var false)
|
||||
start (mf/use-var nil)
|
||||
original-value (mf/use-var 0)
|
||||
negate? (true? (:resize-negate? rect-data))
|
||||
axis (:resize-axis rect-data)
|
||||
|
||||
on-pointer-down
|
||||
(mf/use-fn
|
||||
(mf/deps frame-id rect-data padding-num)
|
||||
(fn [event]
|
||||
(dom/capture-pointer event)
|
||||
(reset! resizing? true)
|
||||
(reset! start (dom/get-client-position event))
|
||||
(reset! original-value (:initial-value rect-data))))
|
||||
|
||||
on-lost-pointer-capture
|
||||
(mf/use-fn
|
||||
(mf/deps frame-id padding-num padding)
|
||||
(fn [event]
|
||||
(dom/release-pointer event)
|
||||
(reset! resizing? false)
|
||||
(reset! start nil)
|
||||
(reset! original-value 0)
|
||||
(st/emit! (dwm/apply-modifiers))))
|
||||
|
||||
on-pointer-move
|
||||
(mf/use-fn
|
||||
(mf/deps frame-id padding-num padding hover-all? hover-v? hover-h?)
|
||||
(fn [event]
|
||||
(let [pos (dom/get-client-position event)]
|
||||
(reset! mouse-pos (point->viewport pos))
|
||||
(when @resizing?
|
||||
(let [delta (-> (gpt/to-vec @start pos)
|
||||
(cond-> negate? gpt/negate)
|
||||
(get axis))
|
||||
val (int (max (+ @original-value (/ delta zoom)) 0))
|
||||
layout-padding (cond
|
||||
hover-all? (assoc padding :p1 val :p2 val :p3 val :p4 val)
|
||||
hover-v? (assoc padding :p1 val :p3 val)
|
||||
hover-h? (assoc padding :p2 val :p4 val)
|
||||
:else (assoc padding padding-num val))
|
||||
|
||||
|
||||
layout-padding-type (if (= (:p1 padding) (:p2 padding) (:p3 padding) (:p4 padding)) :simple :multiple)
|
||||
modifiers (dwm/create-modif-tree [frame-id]
|
||||
(-> (ctm/empty)
|
||||
(ctm/change-property :layout-padding layout-padding)
|
||||
(ctm/change-property :layout-padding-type layout-padding-type)))]
|
||||
(reset! hover-value val)
|
||||
(st/emit! (dwm/set-modifiers modifiers)))))))]
|
||||
|
||||
[:g.padding-rect
|
||||
[:rect.info-area
|
||||
{:x (:x rect-data)
|
||||
:y (:y rect-data)
|
||||
:width (max 0 (:width rect-data))
|
||||
:height (max 0 (:height rect-data))
|
||||
|
||||
:on-pointer-enter on-pointer-enter
|
||||
:on-pointer-leave on-pointer-leave
|
||||
:on-pointer-move on-pointer-move
|
||||
:on-pointer-down on-move-selected
|
||||
:on-context-menu on-context-menu
|
||||
:style {:fill (if (or hover? selected?) fcc/distance-color "none")
|
||||
:opacity (if selected? 0.5 0.25)}}]
|
||||
|
||||
(let [handle-width
|
||||
(if (= axis :x)
|
||||
(/ 2 zoom)
|
||||
(min (* (:width rect-data) 0.5) (/ 20 zoom)))
|
||||
|
||||
handle-height
|
||||
(if (= axis :y)
|
||||
(/ 2 zoom)
|
||||
(min (* (:height rect-data) 0.5) (/ 30 zoom)))]
|
||||
[:rect.handle
|
||||
{:x (+ (:x rect-data) (/ (- (:width rect-data) handle-width) 2))
|
||||
:y (+ (:y rect-data) (/ (- (:height rect-data) handle-height) 2))
|
||||
:width handle-width
|
||||
:height handle-height
|
||||
:on-pointer-enter on-pointer-enter
|
||||
:on-pointer-leave on-pointer-leave
|
||||
:on-pointer-down on-pointer-down
|
||||
:on-lost-pointer-capture on-lost-pointer-capture
|
||||
:on-pointer-move on-pointer-move
|
||||
:on-context-menu on-context-menu
|
||||
:class (when (or hover? selected?)
|
||||
(if (= (:resize-axis rect-data) :x) (cur/get-dynamic "resize-ew" 0) (cur/get-dynamic "resize-ew" 90)))
|
||||
:style {:fill (if (or hover? selected?) fcc/distance-color "none")
|
||||
:opacity (if selected? 0 1)}}])]))
|
||||
|
||||
(mf/defc padding-rects
|
||||
[{:keys [frame zoom alt? shift? on-move-selected on-context-menu]}]
|
||||
(let [frame-id (:id frame)
|
||||
paddings-selected (mf/deref refs/workspace-paddings-selected)
|
||||
hover-value (mf/use-var 0)
|
||||
mouse-pos (mf/use-var nil)
|
||||
hover (mf/use-var nil)
|
||||
hover-all? (and (not (nil? @hover)) alt?)
|
||||
hover-v? (and (or (= @hover :p1) (= @hover :p3)) shift?)
|
||||
hover-h? (and (or (= @hover :p2) (= @hover :p4)) shift?)
|
||||
padding (:layout-padding frame)
|
||||
{:keys [width height x1 x2 y1 y2]} (:selrect frame)
|
||||
on-pointer-enter (fn [hover-type val]
|
||||
(reset! hover hover-type)
|
||||
(reset! hover-value val))
|
||||
on-pointer-leave #(reset! hover nil)
|
||||
pill-width (/ fcc/flex-display-pill-width zoom)
|
||||
pill-height (/ fcc/flex-display-pill-height zoom)
|
||||
hover? #(or hover-all?
|
||||
(and (or (= % :p1) (= % :p3)) hover-v?)
|
||||
(and (or (= % :p2) (= % :p4)) hover-h?)
|
||||
(= @hover %))
|
||||
negate {:p1 (if (:flip-y frame) true false)
|
||||
:p2 (if (:flip-x frame) true false)
|
||||
:p3 (if (:flip-y frame) true false)
|
||||
:p4 (if (:flip-x frame) true false)}
|
||||
negate (cond-> negate
|
||||
(not= :auto (:layout-item-h-sizing frame)) (assoc :p2 (not (:p2 negate)))
|
||||
(not= :auto (:layout-item-v-sizing frame)) (assoc :p3 (not (:p3 negate))))
|
||||
|
||||
padding-rect-data {:p1 {:key (str frame-id "-p1")
|
||||
:x x1
|
||||
:y (if (:flip-y frame) (- y2 (:p1 padding)) y1)
|
||||
:width width
|
||||
:height (:p1 padding)
|
||||
:initial-value (:p1 padding)
|
||||
:resize-type (if (:flip-y frame) :bottom :top)
|
||||
:resize-axis :y
|
||||
:resize-negate? (:p1 negate)}
|
||||
:p2 {:key (str frame-id "-p2")
|
||||
:x (if (:flip-x frame) x1 (- x2 (:p2 padding)))
|
||||
:y y1
|
||||
:width (:p2 padding)
|
||||
:height height
|
||||
:initial-value (:p2 padding)
|
||||
:resize-type :left
|
||||
:resize-axis :x
|
||||
:resize-negate? (:p2 negate)}
|
||||
:p3 {:key (str frame-id "-p3")
|
||||
:x x1
|
||||
:y (if (:flip-y frame) y1 (- y2 (:p3 padding)))
|
||||
:width width
|
||||
:height (:p3 padding)
|
||||
:initial-value (:p3 padding)
|
||||
:resize-type :bottom
|
||||
:resize-axis :y
|
||||
:resize-negate? (:p3 negate)}
|
||||
:p4 {:key (str frame-id "-p4")
|
||||
:x (if (:flip-x frame) (- x2 (:p4 padding)) x1)
|
||||
:y y1
|
||||
:width (:p4 padding)
|
||||
:height height
|
||||
:initial-value (:p4 padding)
|
||||
:resize-type (if (:flip-x frame) :right :left)
|
||||
:resize-axis :x
|
||||
:resize-negate? (:p4 negate)}}]
|
||||
|
||||
[:g.paddings {:pointer-events "visible"}
|
||||
(for [[padding-num rect-data] padding-rect-data]
|
||||
[:& padding-display
|
||||
{:key (:key rect-data)
|
||||
:frame-id frame-id
|
||||
:zoom zoom
|
||||
:hover-all? hover-all?
|
||||
:hover-v? hover-v?
|
||||
:hover-h? hover-h?
|
||||
:padding padding
|
||||
:mouse-pos mouse-pos
|
||||
:hover-value hover-value
|
||||
:padding-num padding-num
|
||||
:on-pointer-enter (partial on-pointer-enter padding-num (get padding padding-num))
|
||||
:on-pointer-leave on-pointer-leave
|
||||
:on-move-selected on-move-selected
|
||||
:on-context-menu on-context-menu
|
||||
:hover? (hover? padding-num)
|
||||
:selected? (get paddings-selected padding-num)
|
||||
:rect-data rect-data}])
|
||||
(when @hover
|
||||
[:& fcc/flex-display-pill
|
||||
{:height pill-height
|
||||
:width pill-width
|
||||
:font-size (/ fcc/font-size zoom)
|
||||
:border-radius (/ fcc/flex-display-pill-border-radius zoom)
|
||||
:color fcc/distance-color
|
||||
:x (:x @mouse-pos)
|
||||
:y (- (:y @mouse-pos) pill-width)
|
||||
:value @hover-value}])]))
|
||||
|
||||
(mf/defc padding-control
|
||||
[{:keys [frame zoom alt? shift? on-move-selected on-context-menu]}]
|
||||
(when frame
|
||||
[:g.measurement-gaps {:pointer-events "none"}
|
||||
[:g.hover-shapes
|
||||
[:& padding-rects
|
||||
{:frame frame
|
||||
:zoom zoom
|
||||
:alt? alt?
|
||||
:shift? shift?
|
||||
:on-move-selected on-move-selected
|
||||
:on-context-menu on-context-menu}]]]))
|
|
@ -8,24 +8,12 @@
|
|||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.rect :as grc]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.geom.shapes.flex-layout :as gsl]
|
||||
[app.common.geom.shapes.points :as gpo]
|
||||
[app.common.math :as mth]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace.modifiers :as dwm]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.css-cursors :as cur]
|
||||
[app.main.ui.formats :as fmt]
|
||||
[app.main.ui.workspace.viewport.viewport-ref :refer [point->viewport]]
|
||||
[app.util.dom :as dom]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
;; ------------------------------------------------
|
||||
|
@ -57,9 +45,6 @@
|
|||
(def distance-pill-height 16)
|
||||
(def distance-line-stroke 1)
|
||||
(def warning-color "var(--color-warning)")
|
||||
(def flex-display-pill-width 40)
|
||||
(def flex-display-pill-height 20)
|
||||
(def flex-display-pill-border-radius 4)
|
||||
|
||||
;; ------------------------------------------------
|
||||
;; HELPERS
|
||||
|
@ -277,600 +262,3 @@
|
|||
[:& size-display {:selrect hover-selrect :zoom zoom}]
|
||||
[:& distance-display {:from hover-selrect :to selected-selrect :zoom zoom :bounds bounds-selrect}]])])))
|
||||
|
||||
|
||||
|
||||
(mf/defc flex-display-pill [{:keys [x y width height font-size border-radius value color]}]
|
||||
[:g.distance-pill
|
||||
[:rect {:x x
|
||||
:y y
|
||||
:width width
|
||||
:height height
|
||||
:rx border-radius
|
||||
:ry border-radius
|
||||
:style {:fill color}}]
|
||||
|
||||
[:text {:x (+ x (/ width 2))
|
||||
:y (+ y (/ height 2))
|
||||
:text-anchor "middle"
|
||||
:dominant-baseline "central"
|
||||
:style {:fill distance-text-color
|
||||
:font-size font-size}}
|
||||
(fmt/format-number (or value 0))]])
|
||||
|
||||
|
||||
(mf/defc padding-display [{:keys [frame-id zoom hover-all? hover-v? hover-h? padding-num padding on-pointer-enter on-pointer-leave
|
||||
rect-data hover? selected? mouse-pos hover-value]}]
|
||||
(let [resizing? (mf/use-var false)
|
||||
start (mf/use-var nil)
|
||||
original-value (mf/use-var 0)
|
||||
negate? (true? (:resize-negate? rect-data))
|
||||
axis (:resize-axis rect-data)
|
||||
|
||||
on-pointer-down
|
||||
(mf/use-fn
|
||||
(mf/deps frame-id rect-data padding-num)
|
||||
(fn [event]
|
||||
(dom/capture-pointer event)
|
||||
(reset! resizing? true)
|
||||
(reset! start (dom/get-client-position event))
|
||||
(reset! original-value (:initial-value rect-data))))
|
||||
|
||||
on-lost-pointer-capture
|
||||
(mf/use-fn
|
||||
(mf/deps frame-id padding-num padding)
|
||||
(fn [event]
|
||||
(dom/release-pointer event)
|
||||
(reset! resizing? false)
|
||||
(reset! start nil)
|
||||
(reset! original-value 0)
|
||||
(st/emit! (dwm/apply-modifiers))))
|
||||
|
||||
on-pointer-move
|
||||
(mf/use-fn
|
||||
(mf/deps frame-id padding-num padding hover-all? hover-v? hover-h?)
|
||||
(fn [event]
|
||||
(let [pos (dom/get-client-position event)]
|
||||
(reset! mouse-pos (point->viewport pos))
|
||||
(when @resizing?
|
||||
(let [delta (-> (gpt/to-vec @start pos)
|
||||
(cond-> negate? gpt/negate)
|
||||
(get axis))
|
||||
val (int (max (+ @original-value (/ delta zoom)) 0))
|
||||
layout-padding (cond
|
||||
hover-all? (assoc padding :p1 val :p2 val :p3 val :p4 val)
|
||||
hover-v? (assoc padding :p1 val :p3 val)
|
||||
hover-h? (assoc padding :p2 val :p4 val)
|
||||
:else (assoc padding padding-num val))
|
||||
|
||||
|
||||
layout-padding-type (if (= (:p1 padding) (:p2 padding) (:p3 padding) (:p4 padding)) :simple :multiple)
|
||||
modifiers (dwm/create-modif-tree [frame-id]
|
||||
(-> (ctm/empty)
|
||||
(ctm/change-property :layout-padding layout-padding)
|
||||
(ctm/change-property :layout-padding-type layout-padding-type)))]
|
||||
(reset! hover-value val)
|
||||
(st/emit! (dwm/set-modifiers modifiers)))))))]
|
||||
|
||||
[:rect.padding-rect {:x (:x rect-data)
|
||||
:y (:y rect-data)
|
||||
:width (max 0 (:width rect-data))
|
||||
:height (max 0 (:height rect-data))
|
||||
:on-pointer-enter on-pointer-enter
|
||||
:on-pointer-leave on-pointer-leave
|
||||
:on-pointer-down on-pointer-down
|
||||
:on-lost-pointer-capture on-lost-pointer-capture
|
||||
:on-pointer-move on-pointer-move
|
||||
:class (when (or hover? selected?)
|
||||
(if (= (:resize-axis rect-data) :x) (cur/get-dynamic "resize-ew" 0) (cur/get-dynamic "resize-ew" 90)))
|
||||
:style {:fill (if (or hover? selected?) distance-color "none")
|
||||
:opacity (if selected? 0.5 0.25)}}]))
|
||||
|
||||
(mf/defc padding-rects [{:keys [frame zoom alt? shift?]}]
|
||||
(let [frame-id (:id frame)
|
||||
paddings-selected (mf/deref refs/workspace-paddings-selected)
|
||||
hover-value (mf/use-var 0)
|
||||
mouse-pos (mf/use-var nil)
|
||||
hover (mf/use-var nil)
|
||||
hover-all? (and (not (nil? @hover)) alt?)
|
||||
hover-v? (and (or (= @hover :p1) (= @hover :p3)) shift?)
|
||||
hover-h? (and (or (= @hover :p2) (= @hover :p4)) shift?)
|
||||
padding (:layout-padding frame)
|
||||
{:keys [width height x1 x2 y1 y2]} (:selrect frame)
|
||||
on-pointer-enter (fn [hover-type val]
|
||||
(reset! hover hover-type)
|
||||
(reset! hover-value val))
|
||||
on-pointer-leave #(reset! hover nil)
|
||||
pill-width (/ flex-display-pill-width zoom)
|
||||
pill-height (/ flex-display-pill-height zoom)
|
||||
hover? #(or hover-all?
|
||||
(and (or (= % :p1) (= % :p3)) hover-v?)
|
||||
(and (or (= % :p2) (= % :p4)) hover-h?)
|
||||
(= @hover %))
|
||||
negate {:p1 (if (:flip-y frame) true false)
|
||||
:p2 (if (:flip-x frame) true false)
|
||||
:p3 (if (:flip-y frame) true false)
|
||||
:p4 (if (:flip-x frame) true false)}
|
||||
negate (cond-> negate
|
||||
(not= :auto (:layout-item-h-sizing frame)) (assoc :p2 (not (:p2 negate)))
|
||||
(not= :auto (:layout-item-v-sizing frame)) (assoc :p3 (not (:p3 negate))))
|
||||
|
||||
padding-rect-data {:p1 {:key (str frame-id "-p1")
|
||||
:x x1
|
||||
:y (if (:flip-y frame) (- y2 (:p1 padding)) y1)
|
||||
:width width
|
||||
:height (:p1 padding)
|
||||
:initial-value (:p1 padding)
|
||||
:resize-type (if (:flip-y frame) :bottom :top)
|
||||
:resize-axis :y
|
||||
:resize-negate? (:p1 negate)}
|
||||
:p2 {:key (str frame-id "-p2")
|
||||
:x (if (:flip-x frame) x1 (- x2 (:p2 padding)))
|
||||
:y y1
|
||||
:width (:p2 padding)
|
||||
:height height
|
||||
:initial-value (:p2 padding)
|
||||
:resize-type :left
|
||||
:resize-axis :x
|
||||
:resize-negate? (:p2 negate)}
|
||||
:p3 {:key (str frame-id "-p3")
|
||||
:x x1
|
||||
:y (if (:flip-y frame) y1 (- y2 (:p3 padding)))
|
||||
:width width
|
||||
:height (:p3 padding)
|
||||
:initial-value (:p3 padding)
|
||||
:resize-type :bottom
|
||||
:resize-axis :y
|
||||
:resize-negate? (:p3 negate)}
|
||||
:p4 {:key (str frame-id "-p4")
|
||||
:x (if (:flip-x frame) (- x2 (:p4 padding)) x1)
|
||||
:y y1
|
||||
:width (:p4 padding)
|
||||
:height height
|
||||
:initial-value (:p4 padding)
|
||||
:resize-type (if (:flip-x frame) :right :left)
|
||||
:resize-axis :x
|
||||
:resize-negate? (:p4 negate)}}]
|
||||
|
||||
[:g.paddings {:pointer-events "visible"}
|
||||
(for [[padding-num rect-data] padding-rect-data]
|
||||
[:& padding-display {:key (:key rect-data)
|
||||
:frame-id frame-id
|
||||
:zoom zoom
|
||||
:hover-all? hover-all?
|
||||
:hover-v? hover-v?
|
||||
:hover-h? hover-h?
|
||||
:padding padding
|
||||
:mouse-pos mouse-pos
|
||||
:hover-value hover-value
|
||||
:padding-num padding-num
|
||||
:on-pointer-enter (partial on-pointer-enter padding-num (get padding padding-num))
|
||||
:on-pointer-leave on-pointer-leave
|
||||
:hover? (hover? padding-num)
|
||||
:selected? (get paddings-selected padding-num)
|
||||
:rect-data rect-data}])
|
||||
(when @hover
|
||||
[:& flex-display-pill {:height pill-height
|
||||
:width pill-width
|
||||
:font-size (/ font-size zoom)
|
||||
:border-radius (/ flex-display-pill-border-radius zoom)
|
||||
:color distance-color
|
||||
:x (:x @mouse-pos)
|
||||
:y (- (:y @mouse-pos) pill-width)
|
||||
:value @hover-value}])]))
|
||||
|
||||
(mf/defc margin-display [{:keys [shape-id zoom hover-all? hover-v? hover-h? margin-num margin on-pointer-enter on-pointer-leave
|
||||
rect-data hover? selected? mouse-pos hover-value]}]
|
||||
(let [resizing? (mf/use-var false)
|
||||
start (mf/use-var nil)
|
||||
original-value (mf/use-var 0)
|
||||
negate? (true? (:resize-negate? rect-data))
|
||||
axis (:resize-axis rect-data)
|
||||
|
||||
on-pointer-down
|
||||
(mf/use-fn
|
||||
(mf/deps shape-id margin-num margin)
|
||||
(fn [event]
|
||||
(dom/capture-pointer event)
|
||||
(reset! resizing? true)
|
||||
(reset! start (dom/get-client-position event))
|
||||
(reset! original-value (:initial-value rect-data))))
|
||||
|
||||
on-lost-pointer-capture
|
||||
(mf/use-fn
|
||||
(mf/deps shape-id margin-num margin)
|
||||
(fn [event]
|
||||
(dom/release-pointer event)
|
||||
(reset! resizing? false)
|
||||
(reset! start nil)
|
||||
(reset! original-value 0)
|
||||
(st/emit! (dwm/apply-modifiers))))
|
||||
|
||||
on-pointer-move
|
||||
(mf/use-fn
|
||||
(mf/deps shape-id margin-num margin hover-all? hover-v? hover-h?)
|
||||
(fn [event]
|
||||
(let [pos (dom/get-client-position event)]
|
||||
(reset! mouse-pos (point->viewport pos))
|
||||
(when @resizing?
|
||||
(let [delta (-> (gpt/to-vec @start pos)
|
||||
(cond-> negate? gpt/negate)
|
||||
(get axis))
|
||||
val (int (max (+ @original-value (/ delta zoom)) 0))
|
||||
layout-item-margin (cond
|
||||
hover-all? (assoc margin :m1 val :m2 val :m3 val :m4 val)
|
||||
hover-v? (assoc margin :m1 val :m3 val)
|
||||
hover-h? (assoc margin :m2 val :m4 val)
|
||||
:else (assoc margin margin-num val))
|
||||
layout-item-margin-type (if (= (:m1 margin) (:m2 margin) (:m3 margin) (:m4 margin)) :simple :multiple)
|
||||
modifiers (dwm/create-modif-tree [shape-id]
|
||||
(-> (ctm/empty)
|
||||
(ctm/change-property :layout-item-margin layout-item-margin)
|
||||
(ctm/change-property :layout-item-margin-type layout-item-margin-type)))]
|
||||
(reset! hover-value val)
|
||||
(st/emit! (dwm/set-modifiers modifiers)))))))]
|
||||
|
||||
[:rect.margin-rect {:x (:x rect-data)
|
||||
:y (:y rect-data)
|
||||
:width (:width rect-data)
|
||||
:height (:height rect-data)
|
||||
:on-pointer-enter on-pointer-enter
|
||||
:on-pointer-leave on-pointer-leave
|
||||
:on-pointer-down on-pointer-down
|
||||
:on-lost-pointer-capture on-lost-pointer-capture
|
||||
:on-pointer-move on-pointer-move
|
||||
:class (when (or hover? selected?)
|
||||
(if (= (:resize-axis rect-data) :x) (cur/get-dynamic "resize-ew" 0) (cur/get-dynamic "resize-ew" 90)))
|
||||
:style {:fill (if (or hover? selected?) warning-color "none")
|
||||
:opacity (if selected? 0.5 0.25)}}]))
|
||||
|
||||
(mf/defc margin-rects [{:keys [shape frame zoom alt? shift?]}]
|
||||
(let [shape-id (:id shape)
|
||||
pill-width (/ flex-display-pill-width zoom)
|
||||
pill-height (/ flex-display-pill-height zoom)
|
||||
margins-selected (mf/deref refs/workspace-margins-selected)
|
||||
hover-value (mf/use-var 0)
|
||||
mouse-pos (mf/use-var nil)
|
||||
hover (mf/use-var nil)
|
||||
hover-all? (and (not (nil? @hover)) alt?)
|
||||
hover-v? (and (or (= @hover :m1) (= @hover :m3)) shift?)
|
||||
hover-h? (and (or (= @hover :m2) (= @hover :m4)) shift?)
|
||||
margin (:layout-item-margin shape)
|
||||
{:keys [width height x1 x2 y1 y2]} (:selrect shape)
|
||||
on-pointer-enter (fn [hover-type val]
|
||||
(reset! hover hover-type)
|
||||
(reset! hover-value val))
|
||||
on-pointer-leave #(reset! hover nil)
|
||||
hover? #(or hover-all?
|
||||
(and (or (= % :m1) (= % :m3)) hover-v?)
|
||||
(and (or (= % :m2) (= % :m4)) hover-h?)
|
||||
(= @hover %))
|
||||
margin-display-data {:m1 {:key (str shape-id "-m1")
|
||||
:x x1
|
||||
:y (if (:flip-y frame) y2 (- y1 (:m1 margin)))
|
||||
:width width
|
||||
:height (:m1 margin)
|
||||
:initial-value (:m1 margin)
|
||||
:resize-type :top
|
||||
:resize-axis :y
|
||||
:resize-negate? (:flip-y frame)}
|
||||
:m2 {:key (str shape-id "-m2")
|
||||
:x (if (:flip-x frame) (- x1 (:m2 margin)) x2)
|
||||
:y y1
|
||||
:width (:m2 margin)
|
||||
:height height
|
||||
:initial-value (:m2 margin)
|
||||
:resize-type :left
|
||||
:resize-axis :x
|
||||
:resize-negate? (:flip-x frame)}
|
||||
:m3 {:key (str shape-id "-m3")
|
||||
:x x1
|
||||
:y (if (:flip-y frame) (- y1 (:m3 margin)) y2)
|
||||
:width width
|
||||
:height (:m3 margin)
|
||||
:initial-value (:m3 margin)
|
||||
:resize-type :top
|
||||
:resize-axis :y
|
||||
:resize-negate? (:flip-y frame)}
|
||||
:m4 {:key (str shape-id "-m4")
|
||||
:x (if (:flip-x frame) x2 (- x1 (:m4 margin)))
|
||||
:y y1
|
||||
:width (:m4 margin)
|
||||
:height height
|
||||
:initial-value (:m4 margin)
|
||||
:resize-type :left
|
||||
:resize-axis :x
|
||||
:resize-negate? (:flip-x frame)}}]
|
||||
|
||||
[:g.margins {:pointer-events "visible"}
|
||||
(for [[margin-num rect-data] margin-display-data]
|
||||
[:& margin-display
|
||||
{:key (:key rect-data)
|
||||
:shape-id shape-id
|
||||
:zoom zoom
|
||||
:hover-all? hover-all?
|
||||
:hover-v? hover-v?
|
||||
:hover-h? hover-h?
|
||||
:margin-num margin-num
|
||||
:margin margin
|
||||
:on-pointer-enter (partial on-pointer-enter margin-num (get margin margin-num))
|
||||
:on-pointer-leave on-pointer-leave
|
||||
:rect-data rect-data
|
||||
:hover? (hover? margin-num)
|
||||
:selected? (get margins-selected margin-num)
|
||||
:mouse-pos mouse-pos
|
||||
:hover-value hover-value}])
|
||||
|
||||
(when @hover
|
||||
[:& flex-display-pill {:height pill-height
|
||||
:width pill-width
|
||||
:font-size (/ font-size zoom)
|
||||
:border-radius (/ flex-display-pill-border-radius zoom)
|
||||
:color warning-color
|
||||
:x (:x @mouse-pos)
|
||||
:y (- (:y @mouse-pos) pill-width)
|
||||
:value @hover-value}])]))
|
||||
|
||||
(mf/defc gap-display [{:keys [frame-id zoom gap-type gap on-pointer-enter on-pointer-leave
|
||||
rect-data hover? selected? mouse-pos hover-value]}]
|
||||
(let [resizing (mf/use-var nil)
|
||||
start (mf/use-var nil)
|
||||
original-value (mf/use-var 0)
|
||||
negate? (:resize-negate? rect-data)
|
||||
axis (:resize-axis rect-data)
|
||||
|
||||
on-pointer-down
|
||||
(mf/use-fn
|
||||
(mf/deps frame-id gap-type gap)
|
||||
(fn [event]
|
||||
(dom/capture-pointer event)
|
||||
(reset! resizing gap-type)
|
||||
(reset! start (dom/get-client-position event))
|
||||
(reset! original-value (:initial-value rect-data))))
|
||||
|
||||
on-lost-pointer-capture
|
||||
(mf/use-fn
|
||||
(mf/deps frame-id gap-type gap)
|
||||
(fn [event]
|
||||
(dom/release-pointer event)
|
||||
(reset! resizing nil)
|
||||
(reset! start nil)
|
||||
(reset! original-value 0)
|
||||
(st/emit! (dwm/apply-modifiers))))
|
||||
|
||||
on-pointer-move
|
||||
(mf/use-fn
|
||||
(mf/deps frame-id gap-type gap)
|
||||
(fn [event]
|
||||
(let [pos (dom/get-client-position event)]
|
||||
(reset! mouse-pos (point->viewport pos))
|
||||
(when (= @resizing gap-type)
|
||||
(let [delta (-> (gpt/to-vec @start pos)
|
||||
(cond-> negate? gpt/negate)
|
||||
(get axis))
|
||||
val (int (max (+ @original-value (/ delta zoom)) 0))
|
||||
layout-gap (assoc gap gap-type val)
|
||||
modifiers (dwm/create-modif-tree [frame-id] (ctm/change-property (ctm/empty) :layout-gap layout-gap))]
|
||||
|
||||
(reset! hover-value val)
|
||||
(st/emit! (dwm/set-modifiers modifiers)))))))]
|
||||
|
||||
[:rect.gap-rect {:x (:x rect-data)
|
||||
:y (:y rect-data)
|
||||
:width (:width rect-data)
|
||||
:height (:height rect-data)
|
||||
:on-pointer-enter on-pointer-enter
|
||||
:on-pointer-leave on-pointer-leave
|
||||
:on-pointer-down on-pointer-down
|
||||
:on-lost-pointer-capture on-lost-pointer-capture
|
||||
:on-pointer-move on-pointer-move
|
||||
:class (when (or hover? selected?)
|
||||
(if (= (:resize-axis rect-data) :x) (cur/get-dynamic "resize-ew" 0) (cur/get-dynamic "resize-ew" 90)))
|
||||
:style {:fill (if (or hover? selected?) distance-color "none")
|
||||
:opacity (if selected? 0.5 0.25)}}]))
|
||||
|
||||
(mf/defc gap-rects [{:keys [frame zoom]}]
|
||||
(let [frame-id (:id frame)
|
||||
saved-dir (:layout-flex-dir frame)
|
||||
is-col? (or (= :column saved-dir) (= :column-reverse saved-dir))
|
||||
flip-x (:flip-x frame)
|
||||
flip-y (:flip-y frame)
|
||||
pill-width (/ flex-display-pill-width zoom)
|
||||
pill-height (/ flex-display-pill-height zoom)
|
||||
workspace-modifiers (mf/deref refs/workspace-modifiers)
|
||||
gap-selected (mf/deref refs/workspace-gap-selected)
|
||||
hover (mf/use-var nil)
|
||||
hover-value (mf/use-var 0)
|
||||
mouse-pos (mf/use-var nil)
|
||||
padding (:layout-padding frame)
|
||||
gap (:layout-gap frame)
|
||||
{:keys [width height x1 y1]} (:selrect frame)
|
||||
on-pointer-enter (fn [hover-type val]
|
||||
(reset! hover hover-type)
|
||||
(reset! hover-value val))
|
||||
|
||||
on-pointer-leave #(reset! hover nil)
|
||||
negate {:column-gap (if flip-x true false)
|
||||
:row-gap (if flip-y true false)}
|
||||
|
||||
objects (wsh/lookup-page-objects @st/state)
|
||||
children (->> (cfh/get-immediate-children objects frame-id)
|
||||
(remove ctl/position-absolute?))
|
||||
|
||||
children-to-display (if (or (= :row-reverse saved-dir)
|
||||
(= :column-reverse saved-dir))
|
||||
(drop-last children)
|
||||
(rest children))
|
||||
children-to-display (->> children-to-display
|
||||
(map #(gsh/transform-shape % (get-in workspace-modifiers [(:id %) :modifiers]))))
|
||||
|
||||
wrap-blocks
|
||||
(let [block-children (->> children
|
||||
(map #(vector (gpo/parent-coords-bounds (:points %) (:points frame)) %)))
|
||||
bounds (d/lazy-map (keys objects) #(gsh/shape->points (get objects %)))
|
||||
|
||||
layout-data (gsl/calc-layout-data frame (:points frame) block-children bounds objects)
|
||||
layout-bounds (:layout-bounds layout-data)
|
||||
xv #(gpo/start-hv layout-bounds %)
|
||||
yv #(gpo/start-vv layout-bounds %)]
|
||||
(for [{:keys [start-p line-width line-height layout-gap-row layout-gap-col num-children]} (:layout-lines layout-data)]
|
||||
(let [line-width (if is-col? line-width (+ line-width (* (dec num-children) layout-gap-row)))
|
||||
line-height (if is-col? (+ line-height (* (dec num-children) layout-gap-col)) line-height)
|
||||
end-p (-> start-p (gpt/add (xv line-width)) (gpt/add (yv line-height)))]
|
||||
{:x1 (min (:x start-p) (:x end-p))
|
||||
:y1 (min (:y start-p) (:y end-p))
|
||||
:x2 (max (:x start-p) (:x end-p))
|
||||
:y2 (max (:y start-p) (:y end-p))})))
|
||||
|
||||
block-contains
|
||||
(fn [x y block]
|
||||
(if is-col?
|
||||
(<= (:x1 block) x (:x2 block))
|
||||
(<= (:y1 block) y (:y2 block))))
|
||||
|
||||
get-container-block
|
||||
(fn [shape]
|
||||
(let [selrect (:selrect shape)
|
||||
x (/ (+ (:x1 selrect) (:x2 selrect)) 2)
|
||||
y (/ (+ (:y1 selrect) (:y2 selrect)) 2)]
|
||||
(->> wrap-blocks
|
||||
(filter #(block-contains x y %))
|
||||
first)))
|
||||
|
||||
create-cgdd
|
||||
(fn [shape]
|
||||
(let [block (get-container-block shape)
|
||||
x (if flip-x
|
||||
(- (:x1 (:selrect shape))
|
||||
(get-in shape [:layout-item-margin :m2])
|
||||
(:column-gap gap))
|
||||
(+ (:x2 (:selrect shape)) (get-in shape [:layout-item-margin :m2])))
|
||||
y (:y1 block)
|
||||
h (- (:y2 block) (:y1 block))]
|
||||
{:x x
|
||||
:y y
|
||||
:height h
|
||||
:width (:column-gap gap)
|
||||
:initial-value (:column-gap gap)
|
||||
:resize-type :left
|
||||
:resize-axis :x
|
||||
:resize-negate? (:column-gap negate)
|
||||
:gap-type (if is-col? :row-gap :column-gap)}))
|
||||
|
||||
create-cgdd-block
|
||||
(fn [block]
|
||||
(let [x (if flip-x
|
||||
(- (:x1 block) (:column-gap gap))
|
||||
(:x2 block))
|
||||
y (if flip-y
|
||||
(+ y1 (:p3 padding))
|
||||
(+ y1 (:p1 padding)))
|
||||
h (- height (+ (:p1 padding) (:p3 padding)))]
|
||||
{:x x
|
||||
:y y
|
||||
:width (:column-gap gap)
|
||||
:height h
|
||||
:initial-value (:column-gap gap)
|
||||
:resize-type :left
|
||||
:resize-axis :x
|
||||
:resize-negate? (:column-gap negate)
|
||||
:gap-type (if is-col? :column-gap :row-gap)}))
|
||||
|
||||
create-rgdd
|
||||
(fn [shape]
|
||||
(let [block (get-container-block shape)
|
||||
x (:x1 block)
|
||||
y (if flip-y
|
||||
(- (:y1 (:selrect shape))
|
||||
(get-in shape [:layout-item-margin :m3])
|
||||
(:row-gap gap))
|
||||
(+ (:y2 (:selrect shape)) (get-in shape [:layout-item-margin :m3])))
|
||||
w (- (:x2 block) (:x1 block))]
|
||||
{:x x
|
||||
:y y
|
||||
:width w
|
||||
:height (:row-gap gap)
|
||||
:initial-value (:row-gap gap)
|
||||
:resize-type :bottom
|
||||
:resize-axis :y
|
||||
:resize-negate? (:row-gap negate)
|
||||
:gap-type (if is-col? :row-gap :column-gap)}))
|
||||
|
||||
create-rgdd-block
|
||||
(fn [block]
|
||||
(let [x (if flip-x
|
||||
(+ x1 (:p2 padding))
|
||||
(+ x1 (:p4 padding)))
|
||||
y (if flip-y
|
||||
(- (:y1 block) (:row-gap gap))
|
||||
(:y2 block))
|
||||
w (- width (+ (:p2 padding) (:p4 padding)))]
|
||||
{:x x
|
||||
:y y
|
||||
:width w
|
||||
:height (:row-gap gap)
|
||||
:initial-value (:row-gap gap)
|
||||
:resize-type :bottom
|
||||
:resize-axis :y
|
||||
:resize-negate? (:row-gap negate)
|
||||
:gap-type (if is-col? :column-gap :row-gap)}))
|
||||
|
||||
display-blocks (if is-col?
|
||||
(->> (drop-last wrap-blocks)
|
||||
(map create-cgdd-block))
|
||||
(->> (drop-last wrap-blocks)
|
||||
(map create-rgdd-block)))
|
||||
|
||||
display-children (if is-col?
|
||||
(->> children-to-display
|
||||
(map create-rgdd))
|
||||
(->> children-to-display
|
||||
(map create-cgdd)))]
|
||||
|
||||
[:g.gaps {:pointer-events "visible"}
|
||||
(for [[index display-item] (d/enumerate (concat display-blocks display-children))]
|
||||
(let [gap-type (:gap-type display-item)]
|
||||
[:& gap-display {:key (str frame-id index)
|
||||
:frame-id frame-id
|
||||
:zoom zoom
|
||||
:gap-type gap-type
|
||||
:gap gap
|
||||
:on-pointer-enter (partial on-pointer-enter gap-type (get gap gap-type))
|
||||
:on-pointer-leave on-pointer-leave
|
||||
:rect-data display-item
|
||||
:hover? (= @hover gap-type)
|
||||
:selected? (= gap-selected gap-type)
|
||||
:mouse-pos mouse-pos
|
||||
:hover-value hover-value}]))
|
||||
|
||||
(when @hover
|
||||
[:& flex-display-pill {:height pill-height
|
||||
:width pill-width
|
||||
:font-size (/ font-size zoom)
|
||||
:border-radius (/ flex-display-pill-border-radius zoom)
|
||||
:color distance-color
|
||||
:x (:x @mouse-pos)
|
||||
:y (- (:y @mouse-pos) pill-width)
|
||||
:value @hover-value}])]))
|
||||
|
||||
(mf/defc padding
|
||||
[{:keys [frame zoom alt? shift?]}]
|
||||
(when frame
|
||||
[:g.measurement-gaps {:pointer-events "none"}
|
||||
[:g.hover-shapes
|
||||
[:& padding-rects {:frame frame :zoom zoom :alt? alt? :shift? shift?}]]]))
|
||||
|
||||
(mf/defc gap
|
||||
[{:keys [frame zoom]}]
|
||||
(when frame
|
||||
[:g.measurement-gaps {:pointer-events "none"}
|
||||
[:g.hover-shapes
|
||||
[:& gap-rects {:frame frame :zoom zoom}]]]))
|
||||
|
||||
(mf/defc margin
|
||||
[{:keys [shape parent zoom alt? shift?]}]
|
||||
(when shape
|
||||
[:g.measurement-gaps {:pointer-events "none"}
|
||||
[:g.hover-shapes
|
||||
[:& margin-rects {:shape shape :frame parent :zoom zoom :alt? alt? :shift? shift?}]]]))
|
||||
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
[app.main.data.workspace.modifiers :as dwm]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.flex-controls :as mfc]
|
||||
[app.main.ui.hooks :as ui-hooks]
|
||||
[app.main.ui.measurements :as msr]
|
||||
[app.main.ui.shapes.export :as use]
|
||||
|
@ -232,31 +233,32 @@
|
|||
|
||||
disabled-guides? (or drawing-tool transform drawing-path? node-editing?)
|
||||
|
||||
one-selected-shape? (= (count selected-shapes) 1)
|
||||
single-select? (= (count selected-shapes) 1)
|
||||
|
||||
show-padding? (and (nil? transform)
|
||||
one-selected-shape?
|
||||
(= (:type (first selected-shapes)) :frame)
|
||||
(= (:layout (first selected-shapes)) :flex)
|
||||
(zero? (:rotation (first selected-shapes))))
|
||||
first-shape (first selected-shapes)
|
||||
|
||||
show-padding?
|
||||
(and (nil? transform)
|
||||
single-select?
|
||||
(= (:type first-shape) :frame)
|
||||
(= (:layout first-shape) :flex)
|
||||
(zero? (:rotation first-shape)))
|
||||
|
||||
show-margin? (and (nil? transform)
|
||||
one-selected-shape?
|
||||
(= (:layout selected-frame) :flex)
|
||||
(zero? (:rotation (first selected-shapes))))
|
||||
show-margin?
|
||||
(and (nil? transform)
|
||||
single-select?
|
||||
(= (:layout selected-frame) :flex)
|
||||
(zero? (:rotation first-shape)))
|
||||
|
||||
first-selected-shape (first selected-shapes)
|
||||
selecting-first-level-frame? (and one-selected-shape?
|
||||
(cfh/root-frame? first-selected-shape))
|
||||
selecting-first-level-frame? (and single-select? (cfh/root-frame? first-shape))
|
||||
|
||||
offset-x (if selecting-first-level-frame?
|
||||
(:x first-selected-shape)
|
||||
(:x first-shape)
|
||||
(:x selected-frame))
|
||||
|
||||
|
||||
offset-y (if selecting-first-level-frame?
|
||||
(:y (first selected-shapes))
|
||||
(:y first-shape)
|
||||
(:y selected-frame))
|
||||
|
||||
rule-area-size (/ rules/rule-area-size zoom)]
|
||||
|
@ -439,24 +441,28 @@
|
|||
:zoom zoom}])
|
||||
|
||||
(when show-padding?
|
||||
[:*
|
||||
[:& msr/padding
|
||||
{:frame (first selected-shapes)
|
||||
:hover @frame-hover
|
||||
:zoom zoom
|
||||
:alt? @alt?
|
||||
:shift? @shift?}]
|
||||
[:& mfc/padding-control
|
||||
{:frame first-shape
|
||||
:hover @frame-hover
|
||||
:zoom zoom
|
||||
:alt? @alt?
|
||||
:shift? @shift?
|
||||
:on-move-selected on-move-selected
|
||||
:on-context-menu on-menu-selected}])
|
||||
|
||||
[:& msr/gap
|
||||
{:frame (first selected-shapes)
|
||||
:hover @frame-hover
|
||||
:zoom zoom
|
||||
:alt? @alt?
|
||||
:shift? @shift?}]])
|
||||
(when show-padding?
|
||||
[:& mfc/gap-control
|
||||
{:frame first-shape
|
||||
:hover @frame-hover
|
||||
:zoom zoom
|
||||
:alt? @alt?
|
||||
:shift? @shift?
|
||||
:on-move-selected on-move-selected
|
||||
:on-context-menu on-menu-selected}])
|
||||
|
||||
(when show-margin?
|
||||
[:& msr/margin
|
||||
{:shape (first selected-shapes)
|
||||
[:& mfc/margin-control
|
||||
{:shape first-shape
|
||||
:parent selected-frame
|
||||
:hover @frame-hover
|
||||
:zoom zoom
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
(mf/deps id blocked hidden type selected edition drawing-tool text-editing?
|
||||
node-editing? grid-editing? drawing-path? create-comment? @z? @space?
|
||||
panning workspace-read-only?)
|
||||
|
||||
(fn [bevent]
|
||||
;; We need to handle editor related stuff here because
|
||||
;; handling on editor dom node does not works properly.
|
||||
|
@ -127,6 +126,7 @@
|
|||
(not mod?)
|
||||
(not shift?)
|
||||
(not @space?))
|
||||
|
||||
(dom/prevent-default bevent)
|
||||
(dom/stop-propagation bevent)
|
||||
(when-not (or workspace-read-only? @z?)
|
||||
|
|
Loading…
Add table
Reference in a new issue