Changes to the editor UI

This commit is contained in:
alonso.torres 2023-05-08 17:25:22 +02:00
parent 3c8934e847
commit 5925d2520f
16 changed files with 350 additions and 168 deletions

View file

@ -349,6 +349,9 @@
column-tracks (add-auto-size column-tracks column-add-auto)
row-tracks (add-auto-size row-tracks row-add-auto)
column-total-size (tracks-total-size column-tracks)
row-total-size (tracks-total-size row-tracks)
start-p
(cond-> bound-corner
(= :end (:layout-align-content parent))

View file

@ -123,6 +123,10 @@
padding: $size-1;
svg {
fill: $color-gray-20;
&.icon-close {
transform: rotate(45deg);
}
}
&:hover {
background: transparent;

View file

@ -367,7 +367,8 @@ $height-palette-max: 80px;
z-index: 12;
pointer-events: none;
.path-actions {
.path-actions,
.grid-actions {
pointer-events: initial;
display: flex;
flex-direction: row;
@ -378,6 +379,27 @@ $height-palette-max: 80px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}
.grid-actions {
padding-left: 1rem;
gap: 12px;
color: var(--color-gray-60);
align-items: center;
font-size: 12px;
.btn-primary,
.btn-secondary {
height: 24px;
}
.grid-edit-title {
margin-right: 2rem;
}
.grid-edit-board-name {
font-weight: 600;
}
}
.viewport-actions-group {
display: flex;
flex-direction: row;

View file

@ -8,7 +8,8 @@
(:require
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.common.geom.shapes.flex-layout :as gsl]
[app.common.geom.shapes.flex-layout :as gslf]
[app.common.geom.shapes.grid-layout :as gslg]
[app.common.math :as mth]
[app.common.pages.helpers :as cph]
[app.common.types.modifiers :as ctm]
@ -84,7 +85,10 @@
fid (ctst/top-nested-frame objects initial)
flex-layout? (ctl/flex-layout? objects fid)
drop-index (when flex-layout? (gsl/get-drop-index fid objects initial))
grid-layout? (ctl/grid-layout? objects fid)
drop-index (when flex-layout? (gslf/get-drop-index fid objects initial))
drop-cell (when grid-layout? (gslg/get-drop-cell fid objects initial))
shape (get-in state [:workspace-drawing :object])
shape (-> shape
@ -101,6 +105,9 @@
(cond-> (some? drop-index)
(with-meta {:index drop-index}))
(cond-> (some? drop-cell)
(with-meta {:cell drop-cell}))
(assoc :initialized? true)
(assoc :click-draw? true))]
(rx/concat

View file

@ -8,7 +8,8 @@
(:require
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.common.geom.shapes.flex-layout :as gsl]
[app.common.geom.shapes.flex-layout :as gslf]
[app.common.geom.shapes.grid-layout :as gslg]
[app.common.geom.shapes.path :as gsp]
[app.common.types.shape-tree :as ctst]
[app.common.types.shape.layout :as ctl]
@ -53,11 +54,15 @@
position (when start (gpt/point start))
frame-id (ctst/top-nested-frame objects position)
flex-layout? (ctl/flex-layout? objects frame-id)
drop-index (when flex-layout? (gsl/get-drop-index frame-id objects position))]
grid-layout? (ctl/grid-layout? objects frame-id)
drop-index (when flex-layout? (gslf/get-drop-index frame-id objects position))
drop-cell (when grid-layout? (gslg/get-drop-cell frame-id objects position))]
(-> state
(assoc-in [:workspace-drawing :object :frame-id] frame-id)
(cond-> (some? drop-index)
(update-in [:workspace-drawing :object] with-meta {:index drop-index})))))))
(update-in [:workspace-drawing :object] with-meta {:index drop-index}))
(cond-> (some? drop-cell)
(update-in [:workspace-drawing :object] with-meta {:cell drop-cell})))))))
(defn curve-to-path [{:keys [segments] :as shape}]
(let [content (gsp/segments->content segments)

View file

@ -6,6 +6,8 @@
(ns app.main.data.workspace.grid-layout.editor
(:require
[app.common.geom.shapes :as gsh]
[app.main.data.workspace.state-helpers :as wsh]
[potok.core :as ptk]))
(defn hover-grid-cell
@ -42,3 +44,21 @@
ptk/UpdateEvent
(update [_ state]
(update state :workspace-grid-edition dissoc grid-id))))
(defn locate-board
[grid-id]
(ptk/reify ::locate-board
ptk/UpdateEvent
(update [_ state]
(let [objects (wsh/lookup-page-objects state)
srect (get-in objects [grid-id :selrect])]
(prn srect)
(-> state
(update :workspace-local
(fn [{:keys [zoom vport] :as local}]
(let [{:keys [x y width height]} srect
x (+ x (/ width 2) (- (/ (:width vport) 2 zoom)))
y (+ y (/ height 2) (- (/ (:height vport) 2 zoom)))
srect (gsh/make-selrect x y width height)]
(-> local
(update :vbox merge (select-keys srect [:x :y :x1 :x2 :y1 :y2])))))))))))

View file

@ -1,4 +1,4 @@
; This Source Code Form is subject to the terms of the Mozilla Public
;; 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/.
;;

View file

@ -82,6 +82,7 @@
selected)
index (:index (meta attrs))
[row column :as cell] (:cell (meta attrs))
changes (-> changes
(pcb/with-objects objects)
@ -91,6 +92,8 @@
(pcb/add-object shape))
(cond-> (some? (:parent-id attrs))
(pcb/change-parent (:parent-id attrs) [shape] index))
(cond-> (some? cell)
(pcb/update-shapes [(:parent-id shape)] #(ctl/push-into-cell % [id] row column)))
(cond-> (ctl/grid-layout? objects (:parent-id shape))
(pcb/update-shapes [(:parent-id shape)] ctl/assign-cells)))]

View file

@ -151,7 +151,7 @@
(dom/class? node "frame-title")
(let [shape (gsh/transform-shape shape modifiers)
zoom (get-in @st/state [:workspace-local :zoom] 1)
mtx (vwu/title-transform shape zoom)]
mtx (vwu/title-transform shape zoom false)]
(override-transform-att! node "transform" mtx))
(or (= (dom/get-tag-name node) "mask")

View file

@ -53,9 +53,9 @@
(.setPointerCapture editor (.-pointerId bevent))
(.setPointerCapture target (.-pointerId bevent))))
(when (or (dom/class? (dom/get-target bevent) "viewport-controls")
(dom/class? (dom/get-target bevent) "viewport-selrect"))
(dom/child? (dom/get-target bevent) (dom/query ".viewport-controls")))
(dom/stop-propagation bevent)
(when-not @z?
@ -79,7 +79,6 @@
(st/emit! (dw/start-zooming pt)))
(st/emit! (dw/start-panning))))
left-click?
(do
(st/emit! (ms/->MouseEvent :down ctrl? shift? alt? meta?))

View file

@ -38,48 +38,6 @@
:flex (dm/str (fmt/format-number value) "FR")
:auto "AUTO"))
(mf/defc track-marker
{::mf/wrap-props false}
[props]
(let [center (unchecked-get props "center")
value (unchecked-get props "value")
zoom (unchecked-get props "zoom")
marker-width (/ 24 zoom)
marker-h1 (/ 22 zoom)
marker-h2 (/ 8 zoom)
marker-half-width (/ marker-width 2)
marker-half-height (/ (+ marker-h1 marker-h2) 2)
marker-points
(reduce
apply-to-point
[(gpt/subtract center
(gpt/point marker-half-width marker-half-height))]
[#(gpt/add % (gpt/point marker-width 0))
#(gpt/add % (gpt/point 0 marker-h1))
#(gpt/add % (gpt/point (- marker-half-width) marker-h2))
#(gpt/subtract % (gpt/point marker-half-width marker-h2))])
text-x (:x center)
text-y (:y center)]
[:g {:class (css :grid-track-marker)}
[:polygon {:class (css :marker-shape)
:points (->> marker-points
(map #(dm/fmt "%,%" (:x %) (:y %)))
(str/join " "))}]
[:text {:class (css :marker-text)
:x text-x
:y text-y
:width (/ 26.26 zoom)
:height (/ 32 zoom)
:text-anchor "middle"
:dominant-baseline "middle"}
(dm/str value)]]))
(mf/defc grid-editor-frame
{::mf/wrap-props false}
[props]
@ -282,7 +240,22 @@
cell-bounds (gsg/cell-bounds layout-data cell)
cell-origin (gpo/origin cell-bounds)
cell-width (gpo/width-points cell-bounds)
cell-height (gpo/height-points cell-bounds)]
cell-height (gpo/height-points cell-bounds)
handle-pointer-enter
(mf/use-callback
(fn []
(st/emit! (dwge/hover-grid-cell (:id shape) (:id cell) true))))
handle-pointer-leave
(mf/use-callback
(fn []
(st/emit! (dwge/hover-grid-cell (:id shape) (:id cell) false))))
handle-pointer-down
(mf/use-callback
(fn []
(st/emit! (dwge/select-grid-cell (:id shape) (:id cell)))))]
[:g.cell-editor
[:rect
@ -294,9 +267,9 @@
:width cell-width
:height cell-height
:on-pointer-enter #(st/emit! (dwge/hover-grid-cell (:id shape) (:id cell) true))
:on-pointer-leave #(st/emit! (dwge/hover-grid-cell (:id shape) (:id cell) false))
:on-click #(st/emit! (dwge/select-grid-cell (:id shape) (:id cell)))}]
:on-pointer-enter handle-pointer-enter
:on-pointer-leave handle-pointer-leave
:on-pointer-down handle-pointer-down}]
(when selected?
(let [handlers
@ -318,31 +291,17 @@
:direction dir
:layout-data layout-data}])]))]))
(mf/defc resize-track-handler
{::mf/wrap-props false}
[props]
(defn use-resize-track
[type shape index track-before track-after zoom snap-pixel?]
(let [shape (unchecked-get props "shape")
index (unchecked-get props "index")
track-before (unchecked-get props "track-before")
track-after (unchecked-get props "track-after")
{:keys [column-total-size column-total-gap row-total-size row-total-gap]} (unchecked-get props "layout-data")
start-p (unchecked-get props "start-p")
type (unchecked-get props "type")
zoom (unchecked-get props "zoom")
[layout-gap-row layout-gap-col] (ctl/gaps shape)
start-size-before (mf/use-var nil)
(let [start-size-before (mf/use-var nil)
start-size-after (mf/use-var nil)
snap-pixel? (mf/deref refs/snap-pixel?)
handle-drag-start
(mf/use-callback
(mf/deps shape track-before track-after)
(fn []
(prn "???" type (:name shape) index track-before track-after zoom snap-pixel?)
(reset! start-size-before (:size track-before))
(reset! start-size-after (:size track-after))
(let [tracks-prop
@ -387,23 +346,42 @@
(fn []
(reset! start-size-before nil)
(reset! start-size-after nil)
(st/emit! (dwm/apply-modifiers))))
(st/emit! (dwm/apply-modifiers))))]
(use-drag {:on-drag-start handle-drag-start
:on-drag-delta handle-drag-position
:on-drag-end handle-drag-end})))
(mf/defc resize-track-handler
{::mf/wrap-props false}
[props]
(let [shape (unchecked-get props "shape")
index (unchecked-get props "index")
track-before (unchecked-get props "track-before")
track-after (unchecked-get props "track-after")
snap-pixel? (unchecked-get props "snap-pixel?")
{:keys [column-total-size column-total-gap row-total-size row-total-gap]} (unchecked-get props "layout-data")
start-p (unchecked-get props "start-p")
type (unchecked-get props "type")
zoom (unchecked-get props "zoom")
[layout-gap-row layout-gap-col] (ctl/gaps shape)
{:keys [handle-pointer-down handle-lost-pointer-capture handle-pointer-move]}
(use-drag {:on-drag-start handle-drag-start
:on-drag-delta handle-drag-position
:on-drag-end handle-drag-end})
(use-resize-track type shape index track-before track-after zoom snap-pixel?)
[x y width height]
(if (= type :column)
[(- (:x start-p) (max layout-gap-col (/ 8 zoom)))
(- (:y start-p) (/ 40 zoom))
[(- (:x start-p) layout-gap-col (/ (- (max layout-gap-col (/ 16 zoom)) layout-gap-col) 2))
(:y start-p)
(max layout-gap-col (/ 16 zoom))
(+ row-total-size row-total-gap (/ 40 zoom))]
(+ row-total-size row-total-gap)]
[(- (:x start-p) (/ 40 zoom))
(- (:y start-p) (max layout-gap-row (/ 8 zoom)))
(+ column-total-size column-total-gap (/ 40 zoom))
[(:x start-p)
(- (:y start-p) layout-gap-row (/ (- (max layout-gap-row (/ 16 zoom)) layout-gap-row) 2))
(+ column-total-size column-total-gap)
(max layout-gap-row (/ 16 zoom))])]
[:rect.resize-track-handler
@ -419,6 +397,63 @@
:on-pointer-move handle-pointer-move
:style {:fill "transparent"}}]))
(mf/defc track-marker
{::mf/wrap-props false}
[props]
(let [center (unchecked-get props "center")
value (unchecked-get props "value")
zoom (unchecked-get props "zoom")
shape (unchecked-get props "shape")
index (unchecked-get props "index")
type (unchecked-get props "type")
track-before (unchecked-get props "track-before")
track-after (unchecked-get props "track-after")
snap-pixel? (unchecked-get props "snap-pixel?")
marker-width (/ 24 zoom)
marker-h1 (/ 22 zoom)
marker-h2 (/ 8 zoom)
marker-half-width (/ marker-width 2)
marker-half-height (/ (+ marker-h1 marker-h2) 2)
marker-points
(reduce
apply-to-point
[(gpt/subtract center
(gpt/point marker-half-width marker-half-height))]
[#(gpt/add % (gpt/point marker-width 0))
#(gpt/add % (gpt/point 0 marker-h1))
#(gpt/add % (gpt/point (- marker-half-width) marker-h2))
#(gpt/subtract % (gpt/point marker-half-width marker-h2))])
text-x (:x center)
text-y (:y center)
{:keys [handle-pointer-down handle-lost-pointer-capture handle-pointer-move]}
(use-resize-track type shape index track-before track-after zoom snap-pixel?)]
[:g {:on-pointer-down handle-pointer-down
:on-lost-pointer-capture handle-lost-pointer-capture
:on-pointer-move handle-pointer-move
:class (css :grid-track-marker)
:style {:cursor (if (= type :column)
(cur/resize-ew 0)
(cur/resize-ns 0))}}
[:polygon {:class (css :marker-shape)
:points (->> marker-points
(map #(dm/fmt "%,%" (:x %) (:y %)))
(str/join " "))}]
[:text {:class (css :marker-text)
:x text-x
:y text-y
:width (/ 26.26 zoom)
:height (/ 32 zoom)
:text-anchor "middle"
:dominant-baseline "middle"}
(dm/str value)]]))
(mf/defc track
{::mf/wrap [#(mf/memo' % (mf/check-props ["shape" "zoom" "index" "type" "track-data" "layout-data"]))]
::mf/wrap-props false}
@ -427,32 +462,40 @@
zoom (unchecked-get props "zoom")
type (unchecked-get props "type")
index (unchecked-get props "index")
snap-pixel? (unchecked-get props "snap-pixel?")
track-data (unchecked-get props "track-data")
layout-data (unchecked-get props "layout-data")
track-input-ref (mf/use-ref)
[layout-gap-row layout-gap-col] (ctl/gaps shape)
bounds (:points shape)
origin (gpo/origin bounds)
vv #(gpo/start-vv bounds %)
hv #(gpo/start-hv bounds %)
start-p (:start-p track-data)
relative (gpt/to-vec origin start-p)
marker-p
(if (= type :column)
(-> start-p
(-> origin
(gpt/add (hv (:x relative)))
(gpt/subtract (vv (/ 20 zoom)))
(cond-> (not= index 0)
(gpt/subtract (hv (/ layout-gap-col 2)))))
(-> start-p
(-> origin
(gpt/add (vv (:y relative)))
(gpt/subtract (hv (/ 20 zoom)))
(cond-> (not= index 0)
(gpt/subtract (vv (/ layout-gap-row 2))))))
text-p
(if (= type :column)
(-> start-p
(-> origin
(gpt/add (hv (:x relative)))
(gpt/subtract (vv (/ 36 zoom))))
(-> start-p
(-> origin
(gpt/add (vv (:y relative)))
(gpt/subtract (hv (/ (:size track-data) 2)))
(gpt/subtract (hv (/ 16 zoom)))
(gpt/add (vv (/ (:size track-data) 2)))
@ -499,7 +542,9 @@
[text-x text-y text-width text-height]
(if (= type :column)
[(:x text-p) (:y text-p) (max 0 (- (:size track-data) 4)) (/ 32 zoom)]
[(:x text-p) (:y text-p) (:size track-data) (/ 36 zoom)])]
[(:x text-p) (:y text-p) (:size track-data) (/ 36 zoom)])
track-before (get-in layout-data [track-list-prop (dec index)])]
(mf/use-effect
(mf/deps track-data)
@ -509,6 +554,12 @@
[:g.track
[:g {:transform (when (= type :row) (dm/fmt "rotate(-90 % %)" (:x marker-p) (:y marker-p)))}
[:& track-marker {:center marker-p
:index index
:shape shape
:snap-pixel? snap-pixel?
:track-after track-data
:track-before track-before
:type type
:value (dm/str (inc index))
:zoom zoom}]]
[:g {:transform (when (= type :row) (dm/fmt "rotate(-90 % %)" (+ (:x text-p) (/ (:size track-data) 2)) (+ (:y text-p) (/ 36 zoom 2))))}
@ -522,16 +573,17 @@
:on-key-down handle-keydown-track-input
:on-blur handle-blur-track-input}]]]
(let [track-before (get-in layout-data [track-list-prop (dec index)])]
[:& resize-track-handler
{:index index
:shape shape
:layout-data layout-data
:start-p start-p
:type type
:track-before track-before
:track-after track-data
:zoom zoom}])]))
[:& resize-track-handler
{:index index
:layout-data layout-data
:shape shape
:snap-pixel? snap-pixel?
:start-p start-p
:track-after track-data
:track-before track-before
:type type
:zoom zoom}]]))
(mf/defc editor
{::mf/wrap [mf/memo]
@ -547,6 +599,8 @@
shape-ref (mf/use-memo (mf/deps (:id shape)) #(refs/object-by-id (:id shape)))
base-shape (mf/deref shape-ref)
snap-pixel? (mf/deref refs/snap-pixel?)
grid-edition-id-ref (mf/use-memo #(refs/workspace-grid-edition-id (:id shape)))
grid-edition (mf/deref grid-edition-id-ref)
@ -565,9 +619,18 @@
height (gpo/height-points bounds)
origin (gpo/origin bounds)
[layout-gap-row layout-gap-col] (ctl/gaps shape)
{:keys [row-tracks column-tracks] :as layout-data}
(gsg/calc-layout-data shape children bounds)
handle-pointer-down
(mf/use-callback
(fn [event]
(let [left-click? (= 1 (.-which (.-nativeEvent event)))]
(when left-click?
(dom/stop-propagation event)))))
handle-add-column
(mf/use-callback
(mf/deps (:id shape))
@ -581,10 +644,11 @@
(st/emit! (st/emit! (dwsl/add-layout-track [(:id shape)] :row ctl/default-track-value)))))]
(mf/use-effect
(fn []
#(st/emit! (dwge/stop-grid-layout-editing (:id shape)))))
(fn []
#(st/emit! (dwge/stop-grid-layout-editing (:id shape)))))
[:g.grid-editor {:pointer-events (when view-only "none")}
[:g.grid-editor {:pointer-events (when view-only "none")
:on-pointer-down handle-pointer-down}
(when-not view-only
[:*
[:& grid-editor-frame {:zoom zoom
@ -608,57 +672,76 @@
:type :column
:index idx
:layout-data layout-data
:snap-pixel? snap-pixel?
:track-data column-data}])
;; Last track resize handler
(let [last-track (last column-tracks)
start-p (:start-p (last column-tracks))
marker-p (-> start-p
(gpt/subtract (vv (/ 20 zoom)))
(gpt/add (hv (:size last-track))))]
[:g.track
[:& track-marker {:center marker-p
:value (dm/str (inc (count column-tracks)))
:zoom zoom}]
[:& resize-track-handler
{:index (count column-tracks)
:shape shape
:layout-data layout-data
:start-p (-> start-p
(gpt/add (hv (:size last-track)))
(gpt/add (hv (/ 20 zoom))))
:type :column
:track-before (last column-tracks)
:zoom zoom}]])
(when-not (empty? column-tracks)
(let [last-track (last column-tracks)
start-p (:start-p (last column-tracks))
relative (gpt/to-vec origin start-p)
marker-p (-> origin
(gpt/add (hv (:x relative)))
(gpt/subtract (vv (/ 20 zoom)))
(gpt/add (hv (:size last-track))))]
[:g.track
[:& track-marker {:center marker-p
:index (count column-tracks)
:shape shape
:snap-pixel? snap-pixel?
:track-before (last column-tracks)
:type :column
:value (dm/str (inc (count column-tracks)))
:zoom zoom}]
[:& resize-track-handler
{:index (count column-tracks)
:shape shape
:layout-data layout-data
:snap-pixel? snap-pixel?
:start-p (-> start-p (gpt/add (hv (+ layout-gap-col (:size last-track)))))
:type :column
:track-before (last column-tracks)
:zoom zoom}]]))
(for [[idx row-data] (d/enumerate row-tracks)]
[:& track {:key (dm/str "row-track-" idx)
:shape shape
:zoom zoom
:type :row
:index idx
[:& track {:index idx
:key (dm/str "row-track-" idx)
:layout-data layout-data
:track-data row-data}])
:shape shape
:snap-pixel? snap-pixel?
:track-data row-data
:type :row
:zoom zoom}])
(let [last-track (last row-tracks)
start-p (:start-p (last row-tracks))
marker-p (-> start-p
(gpt/subtract (hv (/ 20 zoom)))
(gpt/add (vv (:size last-track))))]
[:g.track
[:g {:transform (dm/fmt "rotate(-90 % %)" (:x marker-p) (:y marker-p))}
[:& track-marker {:center marker-p
:value (dm/str (inc (count row-tracks)))
:zoom zoom}]]
[:& resize-track-handler
{:index (count row-tracks)
:shape shape
:layout-data layout-data
:start-p (-> start-p
(gpt/add (vv (:size last-track))))
:type :row
:track-before (last row-tracks)
:zoom zoom}]])
(when-not (empty? row-tracks)
(let [last-track (last row-tracks)
start-p (:start-p (last row-tracks))
relative (gpt/to-vec origin start-p)
marker-p
(-> origin
(gpt/add (vv (:y relative)))
(gpt/subtract (hv (/ 20 zoom)))
(gpt/add (vv (:size last-track))))]
[:g.track
[:g {:transform (dm/fmt "rotate(-90 % %)" (:x marker-p) (:y marker-p))}
[:& track-marker {:center marker-p
:index (count row-tracks)
:shape shape
:snap-pixel? snap-pixel?
:track-before (last row-tracks)
:type :row
:value (dm/str (inc (count row-tracks)))
:zoom zoom}]]
[:& resize-track-handler
{:index (count row-tracks)
:shape shape
:layout-data layout-data
:start-p (-> start-p
(gpt/add (vv (+ layout-gap-row (:size last-track)))))
:type :row
:track-before (last row-tracks)
:snap-pixel? snap-pixel?
:zoom zoom}]]))
(for [[_ cell] (:layout-grid-cells shape)]
[:& grid-cell {:key (dm/str "cell-" (:id cell))

View file

@ -31,7 +31,7 @@
}
.grid-frame {
fill: transparent;
fill: #F6F6F6;
stroke: var(--color-distance);
stroke-width: calc(1 / var(--zoom));
}

View file

@ -69,7 +69,8 @@
(> (:x cand) (:x cur)) cand
:else cur)))
(defn title-transform [{:keys [points] :as shape} zoom]
(defn title-transform
[{:keys [points] :as shape} zoom grid-edition?]
(let [leftmost (->> points (reduce left?))
topmost (->> points (remove #{leftmost}) (reduce top?))
rightmost (->> points (remove #{leftmost topmost}) (reduce right?))
@ -81,14 +82,18 @@
top-right-angle (gpt/angle top-right)
;; Choose the position that creates the less angle between left-side and top-side
[label-pos angle v-pos]
[label-pos angle h-pos v-pos]
(if (< (mth/abs left-top-angle) (mth/abs top-right-angle))
[leftmost left-top-angle (gpt/perpendicular left-top)]
[topmost top-right-angle (gpt/perpendicular top-right)])
[leftmost left-top-angle left-top (gpt/perpendicular left-top)]
[topmost top-right-angle top-right (gpt/perpendicular top-right)])
delta-x (if grid-edition? 40 0)
delta-y (if grid-edition? 50 10)
label-pos
(gpt/subtract label-pos (gpt/scale (gpt/unit v-pos) (/ 10 zoom)))]
(-> label-pos
(gpt/subtract (gpt/scale (gpt/unit v-pos) (/ delta-y zoom)))
(gpt/subtract (gpt/scale (gpt/unit h-pos) (/ delta-x zoom))))]
(dm/fmt "rotate(% %,%) scale(%, %) translate(%, %)"
;; rotate

View file

@ -12,8 +12,10 @@
[app.common.pages.helpers :as cph]
[app.common.types.container :as ctn]
[app.common.types.shape-tree :as ctt]
[app.common.types.shape.layout :as ctl]
[app.common.uuid :as uuid]
[app.main.data.workspace :as dw]
[app.main.data.workspace.grid-layout.editor :as dwge]
[app.main.data.workspace.interactions :as dwi]
[app.main.refs :as refs]
[app.main.store :as st]
@ -24,6 +26,7 @@
[app.main.ui.workspace.viewport.path-actions :refer [path-actions]]
[app.main.ui.workspace.viewport.utils :as vwu]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[app.util.timers :as ts]
[debug :refer [debug?]]
[rumext.v2 :as mf]))
@ -56,16 +59,34 @@
selected (mf/deref refs/selected-objects)
drawing (mf/deref refs/workspace-drawing)
drawing-obj (:object drawing)
shape (or drawing-obj (-> selected first))]
(when (or (and (= (count selected) 1)
(= (:id shape) edition)
(and (not (cph/text-shape? shape))
(not (cph/frame-shape? shape))))
(and (some? drawing-obj)
(cph/path-shape? drawing-obj)
(not= :curve (:tool drawing))))
shape (or drawing-obj (-> selected first))
single? (= (count selected) 1)
editing? (= (:id shape) edition)
draw-path? (and (some? drawing-obj)
(cph/path-shape? drawing-obj)
(not= :curve (:tool drawing)))
path-edition? (or (and single? editing?
(and (not (cph/text-shape? shape))
(not (cph/frame-shape? shape))))
draw-path?)
grid-edition? (and single? editing? (ctl/grid-layout? shape))]
(cond
path-edition?
[:div.viewport-actions
[:& path-actions {:shape shape}]])))
[:& path-actions {:shape shape}]]
grid-edition?
[:div.viewport-actions
[:div.grid-actions
[:div.grid-edit-title
(tr "workspace.layout_grid.editor.title") " " [:span.grid-edit-board-name (:name shape)]]
[:button.btn-secondary {:on-click #(st/emit! (dwge/locate-board (:id shape)))} "Locate"]
[:button.btn-primary {:on-click #(st/emit! dw/clear-edition-mode)} "Done"]
[:button.btn-icon-basic {:on-click #(st/emit! dw/clear-edition-mode)} i/close]]])))
(mf/defc cursor-tooltip
[{:keys [zoom tooltip] :as props}]
@ -97,7 +118,7 @@
(mf/defc frame-title
{::mf/wrap [mf/memo
#(mf/deferred % ts/raf)]}
[{:keys [frame selected? zoom show-artboard-names? show-id? on-frame-enter on-frame-leave on-frame-select]}]
[{:keys [frame selected? zoom show-artboard-names? show-id? on-frame-enter on-frame-leave on-frame-select grid-edition?]}]
(let [workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
;; Note that we don't use mf/deref to avoid a repaint dependency here
@ -114,8 +135,8 @@
(fn [bevent]
(let [event (.-nativeEvent bevent)]
(when (= 1 (.-which event))
(dom/prevent-default event)
(dom/stop-propagation event)
(dom/prevent-default bevent)
(dom/stop-propagation bevent)
(on-frame-select event (:id frame))))))
on-double-click
@ -150,7 +171,7 @@
(when (not (:hidden frame))
[:g.frame-title {:id (dm/str "frame-title-" (:id frame))
:transform (vwu/title-transform frame zoom)
:transform (vwu/title-transform frame zoom grid-edition?)
:pointer-events (when (:blocked frame) "none")}
(when (:use-for-thumbnail? frame)
[:svg {:x 0
@ -195,7 +216,10 @@
(map (d/getf objects))
selected)
shapes)
focus (unchecked-get props "focus")]
focus (unchecked-get props "focus")
edition (mf/deref refs/selected-edition)
grid-edition? (ctl/grid-layout? objects edition)]
[:g.frame-titles
(for [{:keys [id parent-id] :as shape} shapes]
@ -211,7 +235,8 @@
:show-id? (debug? :shape-titles)
:on-frame-enter on-frame-enter
:on-frame-leave on-frame-leave
:on-frame-select on-frame-select}]))]))
:on-frame-select on-frame-select
:grid-edition? (and (= id edition) grid-edition?)}]))]))
(mf/defc frame-flow
[{:keys [flow frame selected? zoom on-frame-enter on-frame-leave on-frame-select]}]

View file

@ -4957,3 +4957,6 @@ msgstr "Marketing"
#: src/app/main/ui/onboarding/questions.cljs
msgid "questions.student-teacher"
msgstr "Student or teacher"
msgid "workspace.layout_grid.editor.title"
msgstr "Editing grid"

View file

@ -5075,3 +5075,6 @@ msgstr "Marketing"
#: src/app/main/ui/onboarding/questions.cljs
msgid "questions.student-teacher"
msgstr "Estudiante o profesorado"
msgid "workspace.layout_grid.editor.title"
msgstr "Editando rejilla"