0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-10 17:00:36 -05:00

Improve text shape rendering and fix broken behavior.

This commit is contained in:
Andrey Antukh 2016-05-23 16:02:05 +03:00
parent 82f1da06f8
commit 57c53ba6a1
No known key found for this signature in database
GPG key ID: 4DFEBCB8316A8B95

View file

@ -11,11 +11,9 @@
[lentes.core :as l]
[goog.events :as events]
[uxbox.rstore :as rs]
[uxbox.state :as st]
[uxbox.data.shapes :as uds]
[uxbox.ui.core :as ui]
[uxbox.ui.mixins :as mx]
[uxbox.ui.keyboard :as kbd]
[uxbox.ui.shapes.common :as common]
[uxbox.ui.shapes.attrs :as attrs]
[uxbox.util.geom :as geom]
@ -25,124 +23,52 @@
;; --- Events
;; FIXME: try to reuse the common.
(defn on-mouse-down
[event own {:keys [id group] :as shape} selected]
(let [selected? (contains? selected id)
local (:rum/local own)
drawing? @common/drawing-state-l]
(when-not (:blocked shape)
(cond
(or drawing?
(:edition @local)
(and group (:locked (geom/resolve-parent shape))))
nil
(and (not selected?) (empty? selected))
(do
(dom/stop-propagation event)
(ui/acquire-action! "ui.shape.move")
(rs/emit! (uds/select-shape id)))
(and (not selected?) (not (empty? selected)))
(do
(dom/stop-propagation event)
(if (kbd/shift? event)
(rs/emit! (uds/select-shape id))
(rs/emit! (uds/deselect-all)
(uds/select-shape id))))
:else
(do
(dom/stop-propagation event)
(ui/acquire-action! "ui.shape.move"))))))
(defn on-mouse-up
[event {:keys [id group] :as shape}]
(cond
(and group (:locked (geom/resolve-parent shape)))
(defn handle-mouse-down
[event local {:keys [id group] :as shape} selected]
(if (and (not (:blocked shape))
(or @common/drawing-state-l
(:edition @local)
(and group (:locked (geom/resolve-parent shape)))))
nil
:else
(do
(dom/stop-propagation event)
(ui/release-action! "ui.shape"))))
(common/on-mouse-down event shape selected)))
;; --- Text Component
(defn- text-component-did-mount
[own]
(letfn [(on-double-click [ev]
(let [container (mx/get-ref-dom own "container")
local (:rum/local own)]
(swap! local assoc :edition true)
(ui/acquire-action! "ui.text.edit")
(set! (.-contentEditable container) true)
(.setAttribute container "contenteditable" "true")
(.focus container)))
(on-blur [ev]
(let [container (mx/get-ref-dom own "container")
local (:rum/local own)]
(ui/release-action! "ui.text.edit")
(swap! local assoc :edition false)
(set! (.-contentEditable container) false)
(.removeAttribute container "contenteditable")))
(on-input [ev]
(let [content (dom/event->inner-text ev)
sid (:id (first (:rum/props own)))]
(rs/emit! (uds/update-text sid {:content content}))))]
(let [main-dom (mx/get-ref-dom own "main")
cntr-dom (mx/get-ref-dom own "container")
key1 (events/listen main-dom EventType.DBLCLICK on-double-click)
key2 (events/listen cntr-dom EventType.BLUR on-blur)
key3 (events/listen cntr-dom EventType.INPUT on-input)]
(assoc own ::key1 key1 ::key2 key2 ::key3 key3))))
(defn- text-component-will-unmount
[own]
(let [key1 (::key1 own)
key2 (::key2 own)
key3 (::key3 own)]
(events/unlistenByKey key1)
(events/unlistenByKey key2)
(events/unlistenByKey key3)
(dissoc own ::key1 ::key2 ::key3)))
(defn- text-component-transfer-state
[old-own own]
(let [data (select-keys old-own [::key1 ::key2 ::key3])]
(merge own data)))
(declare text-shape)
(declare text-shape-render)
(declare text-shape-edit)
(defn- text-component-render
[own shape]
(let [{:keys [id x1 y1 content group]} shape
selected (rum/react common/selected-shapes-l)
selected? (and (contains? selected id) (= (count selected) 1))
on-mouse-down #(on-mouse-down % own shape selected)
on-mouse-up #(on-mouse-up % shape)
local (:rum/local own)
shape (assoc shape :editing? (:edition @local false))]
(html
[:g.shape {:class (when selected? "selected")
:ref "main"
:on-mouse-down on-mouse-down
:on-mouse-up on-mouse-up}
(text-shape-render own shape)])))
[own {:keys [id x1 y1 content group] :as shape}]
(let [selected (rum/react common/selected-shapes-l)
selected? (and (contains? selected id)
(= (count selected) 1))
local (:rum/local own)]
(letfn [(on-mouse-down [event]
(handle-mouse-down event local shape selected))
(on-mouse-up [event]
(common/on-mouse-up event shape))
(on-done [_]
(swap! local assoc :edition false))
(on-double-click [event]
(swap! local assoc :edition true)
(ui/acquire-action! "ui.text.edit"))]
(html
[:g.shape {:class (when selected? "selected")
:ref "main"
:on-double-click on-double-click
:on-mouse-down on-mouse-down
:on-mouse-up on-mouse-up}
(if (:edition @local false)
(text-shape-edit shape on-done)
(text-shape shape))]))))
(def text-component
(mx/component
{:render text-component-render
:name "text-componet"
:did-mount text-component-did-mount
:will-unmount text-component-will-unmount
:transfer-state text-component-transfer-state
:mixins [mx/static rum/reactive (mx/local)]}))
;; --- Test Shape
;; --- Text Styles Helpers
(def ^:const +style-attrs+ [:font-size])
(def ^:const +select-rect-attrs+
@ -168,6 +94,7 @@
(merge
{:fontSize (str size "px")
:color color
:whiteSpace "pre"
:textAlign align
:fontFamily family
:fontWeight weight
@ -175,8 +102,52 @@
(when line-height {:lineHeight line-height})
(when letter-spacing {:letterSpacing letter-spacing}))))
;; --- Text Shape Edit
(defn- text-shape-edit-did-mount
[own]
(let [[shape] (:rum/props own)
dom (mx/get-ref-dom own "container")]
(set! (.-textContent dom) (:content shape ""))
(.focus dom)
own))
(defn- text-shape-edit-render
[own {:keys [id x1 y1 content] :as shape} on-done]
(let [size (geom/size shape)
style (make-style shape)
rfm (geom/transformation-matrix shape)
props {:x x1 :y y1
:transform (str rfm)}
props (merge props size)]
(letfn [(on-blur [ev]
(ui/release-action! "ui.text.edit")
(on-done))
(on-input [ev]
(let [content (dom/event->inner-text ev)
sid (:id (first (:rum/props own)))]
(rs/emit! (uds/update-text sid {:content content}))))]
(html
[:g
[:rect (merge props +select-rect-attrs+)]
[:foreignObject props
[:p {:ref "container"
:on-blur on-blur
:on-input on-input
:contentEditable true
:style style}]]]))))
(def text-shape-edit
(mx/component
{:render text-shape-edit-render
:did-mount text-shape-edit-did-mount
:name "text-shape-edit"
:mixins [mx/static]}))
;; --- Text Shape
(defn- text-shape-render
[own {:keys [id x1 y1 x2 y2 content drawing? editing?] :as shape}]
[own {:keys [id x1 y1 content] :as shape}]
(let [key (str id)
rfm (geom/transformation-matrix shape)
size (geom/size shape)
@ -185,15 +156,11 @@
attrs (merge props size)
style (make-style shape)]
(html
[:g
(if (or drawing? editing?)
[:g
[:rect (merge attrs +select-rect-attrs+)]])
[:foreignObject attrs
[:p {:ref "container" :style style} content]]])))
[:foreignObject attrs
[:p {:style style} content]])))
;; (def text-shape
;; (mx/component
;; {:render text-shape-render
;; :name "text-shape"
;; :mixins [mx/static]}))
(def text-shape
(mx/component
{:render text-shape-render
:name "text-shape"
:mixins [mx/static]}))