Improvements over text shape

This commit is contained in:
alonso.torres 2020-09-21 16:21:10 +02:00 committed by Andrey Antukh
parent 62a2713c03
commit df70cd5c50
6 changed files with 80 additions and 37 deletions

View file

@ -1456,7 +1456,8 @@
"a" #(st/emit! (select-for-drawing :frame)) "a" #(st/emit! (select-for-drawing :frame))
"b" #(st/emit! (select-for-drawing :rect)) "b" #(st/emit! (select-for-drawing :rect))
"e" #(st/emit! (select-for-drawing :circle)) "e" #(st/emit! (select-for-drawing :circle))
"t" #(st/emit! (select-for-drawing :text)) "t" #(st/emit! dwtxt/start-edit-if-selected
(select-for-drawing :text))
"ctrl+c" #(st/emit! copy-selected) "ctrl+c" #(st/emit! copy-selected)
"ctrl+v" #(st/emit! paste) "ctrl+v" #(st/emit! paste)
"escape" #(st/emit! :interrupt deselect-all) "escape" #(st/emit! :interrupt deselect-all)

View file

@ -186,3 +186,23 @@
(defn update-root-attrs (defn update-root-attrs
[options] [options]
(update-attrs (assoc options :pred is-root-node? :split false))) (update-attrs (assoc options :pred is-root-node? :split false)))
(defn update-overflow-text [id value]
(ptk/reify ::update-overflow-text
ptk/UpdateEvent
(update [_ state]
(let [page-id (:current-page-id state)]
(update-in state [:workspace-data :pages-index page-id :objects id] assoc :overflow-text value)))))
(def start-edit-if-selected
(ptk/reify ::start-edit-if-selected
ptk/UpdateEvent
(update [_ state]
(let [page-id (:current-page-id state)
objects (get-in state [:workspace-data :pages-index page-id :objects])
selected (->> state :workspace-local :selected (map #(get objects %)))]
(cond-> state
(and (= 1 (count selected))
(= (-> selected first :type) :text))
(assoc-in [:workspace-local :edition] (-> selected first :id)))))))

View file

@ -18,6 +18,7 @@
[app.common.pages-helpers :as cph] [app.common.pages-helpers :as cph]
[app.common.spec :as us] [app.common.spec :as us]
[app.main.data.workspace.common :as dwc] [app.main.data.workspace.common :as dwc]
[app.main.data.workspace.texts :as dwt]
[app.main.data.workspace.selection :as dws] [app.main.data.workspace.selection :as dws]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.snap :as snap] [app.main.snap :as snap]
@ -139,8 +140,12 @@
layout (:workspace-layout state) layout (:workspace-layout state)
page-id (:current-page-id state) page-id (:current-page-id state)
objects (dwc/lookup-page-objects state page-id) objects (dwc/lookup-page-objects state page-id)
resizing-shapes (map #(get objects %) ids)] resizing-shapes (map #(get objects %) ids)
text-shapes-ids (->> resizing-shapes
(filter #(= :text (:type %)))
(map :id))]
(rx/concat (rx/concat
(rx/of (dwc/update-shapes text-shapes-ids #(assoc % :grow-type :fixed)))
(->> ms/mouse-position (->> ms/mouse-position
(rx/with-latest vector ms/mouse-position-shift) (rx/with-latest vector ms/mouse-position-shift)
(rx/map normalize-proportion-lock) (rx/map normalize-proportion-lock)

View file

@ -126,7 +126,7 @@
:on-mouse-down on-rotate}])) :on-mouse-down on-rotate}]))
(mf/defc resize-point-handler (mf/defc resize-point-handler
[{:keys [cx cy zoom position on-resize transform rotation color]}] [{:keys [cx cy zoom position on-resize transform rotation color overflow-text]}]
(let [{cx' :x cy' :y} (gpt/transform (gpt/point cx cy) transform) (let [{cx' :x cy' :y} (gpt/transform (gpt/point cx cy) transform)
rot-square (case position rot-square (case position
:top-left 0 :top-left 0
@ -140,7 +140,7 @@
:vectorEffect "non-scaling-stroke" :vectorEffect "non-scaling-stroke"
} }
:fill "#FFFFFF" :fill "#FFFFFF"
:stroke color :stroke (if (and (= position :bottom-right) overflow-text) "red" color)
:cx cx' :cx cx'
:cy cy'}] :cy cy'}]
@ -172,7 +172,7 @@
(mf/defc controls (mf/defc controls
{::mf/wrap-props false} {::mf/wrap-props false}
[props] [props]
(let [shape (obj/get props "shape") (let [{:keys [overflow-text] :as shape} (obj/get props "shape")
zoom (obj/get props "zoom") zoom (obj/get props "zoom")
color (obj/get props "color") color (obj/get props "color")
on-resize (obj/get props "on-resize") on-resize (obj/get props "on-resize")
@ -202,7 +202,8 @@
:on-resize (partial on-resize position) :on-resize (partial on-resize position)
:transform transform :transform transform
:rotation (:rotation shape) :rotation (:rotation shape)
:color color} :color color
:overflow-text overflow-text}
props (map->obj (merge common-props props))] props (map->obj (merge common-props props))]
(case type (case type
:rotation (when (not= :frame (:type shape)) [:> rotation-handler props]) :rotation (when (not= :frame (:type shape)) [:> rotation-handler props])

View file

@ -61,8 +61,6 @@
selected? (and (contains? selected id) selected? (and (contains? selected id)
(= (count selected) 1)) (= (count selected) 1))
calculate-size (mf/use-state false)
on-mouse-down #(handle-mouse-down % shape) on-mouse-down #(handle-mouse-down % shape)
on-context-menu #(common/on-context-menu % shape) on-context-menu #(common/on-context-menu % shape)
@ -73,18 +71,13 @@
(when selected? (when selected?
(st/emit! (dw/start-edition-mode (:id shape)))))] (st/emit! (dw/start-edition-mode (:id shape)))))]
(mf/use-effect
(mf/deps grow-type content width height)
(fn []
(reset! calculate-size true)
(timers/schedule 200 (fn [] (reset! calculate-size false)))))
[:g.shape {:on-double-click on-double-click [:g.shape {:on-double-click on-double-click
:on-mouse-down on-mouse-down :on-mouse-down on-mouse-down
:on-context-menu on-context-menu} :on-context-menu on-context-menu}
[:* [:*
(when (and (not edition?) @calculate-size) (when (not edition?)
[:g {:opacity 0} [:g {:opacity 0
:style {:pointer-events "none"}}
;; We only render the component for its side-effect ;; We only render the component for its side-effect
[:& text-shape-edit {:shape shape [:& text-shape-edit {:shape shape
:read-only? true}]]) :read-only? true}]])
@ -125,7 +118,7 @@
lh (obj/set! "lineHeight" lh)))) lh (obj/set! "lineHeight" lh))))
(defn- generate-text-styles (defn- generate-text-styles
[data] [data on-load-font]
(let [letter-spacing (obj/get data "letter-spacing") (let [letter-spacing (obj/get data "letter-spacing")
text-decoration (obj/get data "text-decoration") text-decoration (obj/get data "text-decoration")
text-transform (obj/get data "text-transform") text-transform (obj/get data "text-transform")
@ -157,7 +150,7 @@
(when (and (string? font-id) (when (and (string? font-id)
(pos? (alength font-id))) (pos? (alength font-id)))
(let [font (get fontsdb font-id)] (let [font (get fontsdb font-id)]
(fonts/ensure-loaded! font-id) (fonts/ensure-loaded! font-id on-load-font)
(let [font-family (or (:family font) (let [font-family (or (:family font)
(obj/get data "fontFamily")) (obj/get data "fontFamily"))
font-variant (d/seek #(= font-variant-id (:id %)) font-variant (d/seek #(= font-variant-id (:id %))
@ -219,7 +212,8 @@
(let [attrs (obj/get props "attributes") (let [attrs (obj/get props "attributes")
childs (obj/get props "children") childs (obj/get props "children")
data (obj/get props "leaf") data (obj/get props "leaf")
style (generate-text-styles data) on-load-font (obj/get props "on-load-font")
style (generate-text-styles data on-load-font)
attrs (obj/set! attrs "style" style)] attrs (obj/set! attrs "style" style)]
[:> :span attrs childs])) [:> :span attrs childs]))
@ -235,9 +229,10 @@
nil)))) nil))))
(defn- render-text (defn- render-text
[props] [on-load-font]
(mf/html (fn [props]
[:> editor-text-node props])) (mf/html
[:> editor-text-node (obj/merge! props #js {:on-load-font on-load-font})])))
;; --- Text Shape Edit ;; --- Text Shape Edit
@ -271,7 +266,7 @@
(when (not read-only?) (when (not read-only?)
(st/emit! dw/clear-edition-mode))) (st/emit! dw/clear-edition-mode)))
on-click on-click-outside
(fn [event] (fn [event]
(dom/prevent-default event) (dom/prevent-default event)
(dom/stop-propagation event) (dom/stop-propagation event)
@ -304,7 +299,7 @@
on-mount on-mount
(fn [] (fn []
(when (not read-only?) (when (not read-only?)
(let [lkey1 (events/listen js/document EventType.CLICK on-click) (let [lkey1 (events/listen js/document EventType.CLICK on-click-outside)
lkey2 (events/listen js/document EventType.KEYUP on-key-up)] lkey2 (events/listen js/document EventType.KEYUP on-key-up)]
(st/emit! (dwt/assign-editor id editor) (st/emit! (dwt/assign-editor id editor)
dwc/start-undo-transaction) dwc/start-undo-transaction)
@ -327,22 +322,42 @@
(let [content (js->clj val :keywordize-keys true) (let [content (js->clj val :keywordize-keys true)
content (first content)] content (first content)]
(st/emit! (dw/update-shape id {:content content})) (st/emit! (dw/update-shape id {:content content}))
(reset! state val)))))] (reset! state val)))))
loaded-fonts (mf/use-var 0)
on-load-font #(swap! loaded-fonts inc)]
(mf/use-effect on-mount) (mf/use-effect on-mount)
(mf/use-effect (mf/use-effect
(mf/deps @state) (mf/deps content)
(fn []
(reset! state (parse-content content))))
;; Checks the size of the wrapper to update if it were necesary
(mf/use-effect
(mf/deps props @loaded-fonts)
(fn [] (fn []
(timers/schedule (timers/schedule
#(if (#{:auto-width :auto-height} grow-type) 250 ;; We need to wait to the text to be rendered. Is there a better alternative?
(let [self-node (mf/ref-val self-ref) #(let [self-node (mf/ref-val self-ref)
paragraph-node (dom/query self-node ".paragraph-set")] paragraph-node (when self-node (dom/query self-node ".paragraph-set"))]
(when paragraph-node (when paragraph-node
(let [{:keys [width height]} (dom/get-bounding-rect paragraph-node)] (let [{:keys [width height]} (dom/get-bounding-rect paragraph-node)]
(st/emit! (dw/update-shape id (if (= grow-type :auto-width) (cond
{:width width :height height} (and (:overflow-text shape) (not= :fixed (:grow-type shape)))
{:height height})))))))))) (st/emit! (dwt/update-overflow-text id false))
(and (= :fixed (:grow-type shape)) (not (:overflow-text shape)) (> height (:height shape)))
(st/emit! (dwt/update-overflow-text id true))
(and (= :fixed (:grow-type shape)) (:overflow-text shape) (<= height (:height shape)))
(st/emit! (dwt/update-overflow-text id false)))
(if (#{:auto-width :auto-height} grow-type)
(st/emit! (dw/update-shape id (if (= grow-type :auto-width)
{:width width :height height}
{:height height}))))))))))
[:foreignObject {:ref self-ref [:foreignObject {:ref self-ref
:transform (geom/transform-matrix shape) :transform (geom/transform-matrix shape)
@ -358,9 +373,10 @@
:spell-check "false" :spell-check "false"
:on-focus on-focus :on-focus on-focus
:class "rich-text" :class "rich-text"
:style {:cursor cur/text} :style {:cursor cur/text
:width (:width shape)}
:render-element #(render-element shape %) :render-element #(render-element shape %)
:render-leaf render-text :render-leaf (render-text on-load-font)
:on-mouse-up on-mouse-up :on-mouse-up on-mouse-up
:on-mouse-down on-mouse-down :on-mouse-down on-mouse-down
:on-blur (fn [event] :on-blur (fn [event]

View file

@ -308,7 +308,7 @@
(st/emit! (ms/->MouseEvent :down ctrl? shift? alt?)) (st/emit! (ms/->MouseEvent :down ctrl? shift? alt?))
(cond (cond
(and (not edition) (= 1 (.-which event))) (and (= 1 (.-which event)))
(if drawing-tool (if drawing-tool
(st/emit! (dd/start-drawing drawing-tool)) (st/emit! (dd/start-drawing drawing-tool))
(st/emit! dw/handle-selection)) (st/emit! dw/handle-selection))