 
 ;; --- 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+

            [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]

    (merge
     {:fontSize (str size "px")
      :color color
      :whiteSpace "pre"
      :textAlign align
      :fontFamily family
      :fontWeight weight
