♻️ Major refactor of page data structure.

In preparation to future collaborative edition.
This commit is contained in:
Andrey Antukh 2019-12-04 20:13:35 +01:00
parent 8c4bdc3f31
commit af62d949d8
33 changed files with 1025 additions and 1124 deletions

View file

@ -29,9 +29,8 @@
(ptk/reify ::start-move-selected
ptk/WatchEvent
(watch [_ state stream]
(let [pid (get-in state [:workspace :current])
flags (get-in state [:workspace pid :flags])
selected (get-in state [:workspace pid :selected])
(let [flags (get-in state [:workspace-local :flags])
selected (get-in state [:workspace-local :selected])
stoper (rx/filter uws/mouse-up? stream)
position @uws/mouse-position]
(rx/concat
@ -40,7 +39,8 @@
(->> (uws/mouse-position-deltas position)
(rx/map #(dw/apply-temporal-displacement-in-bulk selected %))
(rx/take-until stoper))
(rx/of (dw/materialize-current-modifier-in-bulk selected)))))))
(rx/of (dw/materialize-current-modifier-in-bulk selected)
::dw/page-data-update))))))
(defn on-mouse-down
[event {:keys [id type] :as shape} selected]

View file

@ -11,7 +11,6 @@
[lentes.core :as l]
[rumext.core :as mx]
[rumext.alpha :as mf]
[uxbox.main.data.shapes :as uds]
[uxbox.main.data.workspace :as udw]
[uxbox.main.geom :as geom]
[uxbox.main.refs :as refs]

View file

@ -14,7 +14,7 @@
[uxbox.main.data.history :as udh]
[uxbox.main.data.pages :as udp]
[uxbox.main.data.undo :as udu]
[uxbox.main.data.workspace :as dw]
[uxbox.main.data.workspace :as udw]
[uxbox.main.refs :as refs]
[uxbox.main.store :as st]
[uxbox.main.ui.confirm]
@ -22,9 +22,9 @@
[uxbox.main.ui.messages :refer [messages-widget]]
[uxbox.main.ui.workspace.viewport :refer [viewport]]
[uxbox.main.ui.workspace.colorpalette :refer [colorpalette]]
[uxbox.main.ui.workspace.download]
;; [uxbox.main.ui.workspace.download]
[uxbox.main.ui.workspace.header :refer [header]]
[uxbox.main.ui.workspace.images]
;; [uxbox.main.ui.workspace.images]
[uxbox.main.ui.workspace.rules :refer [horizontal-rule vertical-rule]]
[uxbox.main.ui.workspace.scroll :as scroll]
[uxbox.main.ui.workspace.shortcuts :as shortcuts]
@ -55,47 +55,20 @@
(dom/prevent-default event)
(dom/stop-propagation event)
(if (pos? (.-deltaY event))
(st/emit! (dw/decrease-zoom))
(st/emit! (dw/increase-zoom)))
(st/emit! (udw/decrease-zoom))
(st/emit! (udw/increase-zoom)))
(scroll/scroll-to-point dom mouse-point scroll-position))))
(defn- subscribe
[canvas page]
(st/emit! (udp/watch-page-changes (:id page))
(udu/watch-page-changes (:id page))
;; TODO: temporary commented
;; (udh/initialize (:id page))
;; (udh/watch-page-changes (:id page))
(dw/start-shapes-watcher (:id page)))
(let [sub (shortcuts/init)]
#(do (st/emit! ::udp/stop-page-watcher
::udh/stop-page-watcher
::dw/stop-shapes-watcher)
(rx/cancel! sub))))
(mf/defc workspace
[{:keys [page] :as props}]
(let [flags (or (mf/deref refs/flags) #{})
canvas (mf/use-ref nil)
left-sidebar? (not (empty? (keep flags [:layers :sitemap
(mf/defc workspace-content
[{:keys [layout page] :as params}]
(let [canvas (mf/use-ref nil)
left-sidebar? (not (empty? (keep layout [:layers :sitemap
:document-history])))
right-sidebar? (not (empty? (keep flags [:icons :drawtools
right-sidebar? (not (empty? (keep layout [:icons :drawtools
:element-options])))
classes (classnames
:no-tool-bar-right (not right-sidebar?)
:no-tool-bar-left (not left-sidebar?)
:scrolling (:viewport-positionig workspace))]
(mf/use-effect #(subscribe canvas page)
#js [(:id page)])
[:*
[:& messages-widget]
[:& header {:page page
:flags flags
:key (:id page)}]
(when (:colorpalette flags)
[:& colorpalette])
:no-tool-bar-left (not left-sidebar?))]
[:main.main-content
[:section.workspace-content
@ -106,32 +79,45 @@
[:& history-dialog]
;; Rules
(when (contains? flags :rules)
[:& horizontal-rule])
(when (contains? flags :rules)
[:& vertical-rule])
(when (contains? layout :rules)
[:*
[:& horizontal-rule]
[:& vertical-rule]])
[:section.workspace-viewport {:id "workspace-viewport" :ref canvas}
[:& viewport {:page page :key (:id page)}]]]
[:& viewport {:page page}]]]
;; Aside
(when left-sidebar?
[:& left-sidebar {:page page :flags flags}])
[:& left-sidebar {:page page :layout layout}])
(when right-sidebar?
[:& right-sidebar {:page page :flags flags}])]]))
[:& right-sidebar {:page page :layout layout}])]))
(mf/defc workspace
[{:keys [page-id] :as props}]
(let [layout (mf/deref refs/workspace-layout)
flags (mf/deref refs/selected-flags)
page (mf/deref refs/workspace-page)]
[:*
[:& messages-widget]
[:& header {:page page :flags flags}]
(when (:colorpalette flags)
[:& colorpalette])
(when (and layout page)
[:& workspace-content {:layout layout :page page}])]))
(mf/defc workspace-page
[{:keys [project-id page-id] :as props}]
(let [page-iref (mf/use-memo {:deps #js [project-id page-id]
:fn #(-> (l/in [:pages page-id])
(l/derive st/state))})
page (mf/deref page-iref)]
(mf/use-effect
{:deps #js [project-id page-id]
:fn #(st/emit! (dw/initialize project-id page-id))})
(mf/use-effect
{:deps #js [page-id]
:fn (fn []
(let [sub (shortcuts/init)]
(st/emit! (udw/initialize project-id page-id))
#(rx/cancel! sub)))})
[:> rdnd/provider {:backend rdnd/html5}
(when page
[:& workspace {:page page}])]))
[:> rdnd/provider {:backend rdnd/html5}
[:& workspace {:page-id page-id :key page-id}]])

View file

@ -12,7 +12,6 @@
[rumext.alpha :as mf]
[uxbox.main.constants :as c]
[uxbox.main.data.workspace :as dw]
[uxbox.main.data.shapes :as ds]
[uxbox.main.geom :as geom]
[uxbox.main.refs :as refs]
[uxbox.main.store :as st]
@ -73,17 +72,16 @@
(ptk/reify ::start-drawing
ptk/UpdateEvent
(update [_ state]
(update-in state [:workspace :drawing-lock] #(if (nil? %) id %)))
(update-in state [:workspace-local :drawing-lock] #(if (nil? %) id %)))
ptk/WatchEvent
(watch [_ state stream]
(let [pid (get-in state [:workspace :current])
lock (get-in state [:workspace :drawing-lock])]
(let [lock (get-in state [:workspace-local :drawing-lock])]
(if (= lock id)
(rx/merge
(->> (rx/filter #(= % handle-finish-drawing) stream)
(rx/take 1)
(rx/map (fn [_] #(update % :workspace dissoc :drawing-lock))))
(rx/map (fn [_] #(update % :workspace-local dissoc :drawing-lock))))
(rx/of (handle-drawing type)))
(rx/empty)))))))
@ -98,9 +96,8 @@
(ptk/reify ::handle-drawing
ptk/UpdateEvent
(update [_ state]
(let [pid (get-in state [:workspace :current])
data (make-minimal-shape type)]
(update-in state [:workspace pid :drawing] merge data)))
(let [data (make-minimal-shape type)]
(update-in state [:workspace-local :drawing] merge data)))
ptk/WatchEvent
(watch [_ state stream]
@ -111,13 +108,12 @@
(def handle-drawing-generic
(letfn [(initialize-drawing [state point]
(let [pid (get-in state [:workspace :current])
shape (get-in state [:workspace pid :drawing])
(let [shape (get-in state [:workspace-local :drawing])
shape (geom/setup shape {:x1 (:x point)
:y1 (:y point)
:x2 (+ (:x point) 2)
:y2 (+ (:y point) 2)})]
(assoc-in state [:workspace pid :drawing] (assoc shape ::initialized? true))))
(assoc-in state [:workspace-local :drawing] (assoc shape ::initialized? true))))
(resize-shape [shape point lock?]
(let [shape (-> (geom/shape->rect-shape shape)
@ -128,14 +124,12 @@
(assoc shape :modifier-mtx mtx)))
(update-drawing [state point lock?]
(let [pid (get-in state [:workspace :current])]
(update-in state [:workspace pid :drawing] resize-shape point lock?)))]
(update-in state [:workspace-local :drawing] resize-shape point lock?))]
(ptk/reify ::handle-drawing-generic
ptk/WatchEvent
(watch [_ state stream]
(let [pid (get-in state [:workspace :current])
{:keys [zoom flags]} (get-in state [:workspace pid])
(let [{:keys [zoom flags]} (:workspace-local state)
align? (refs/alignment-activated? flags)
stoper? #(or (uws/mouse-up? %) (= % :interrupt))
@ -165,30 +159,26 @@
(= 13 (:key event)))))
(initialize-drawing [state point]
(let [pid (get-in state [:workspace :current])]
(-> state
(assoc-in [:workspace pid :drawing :segments] [point point])
(assoc-in [:workspace pid :drawing ::initialized?] true))))
(-> state
(assoc-in [:workspace-local :drawing :segments] [point point])
(assoc-in [:workspace-local :drawing ::initialized?] true)))
(insert-point-segment [state point]
(let [pid (get-in state [:workspace :current])]
(update-in state [:workspace pid :drawing :segments] (fnil conj []) point)))
(update-in state [:workspace-local :drawing :segments] (fnil conj []) point))
(update-point-segment [state index point]
(let [pid (get-in state [:workspace :current])
segments (count (get-in state [:workspace pid :drawing :segments]))
(let [segments (count (get-in state [:workspace-local :drawing :segments]))
exists? (< -1 index segments)]
(cond-> state
exists? (assoc-in [:workspace pid :drawing :segments index] point))))
exists? (assoc-in [:workspace-local :drawing :segments index] point))))
(remove-dangling-segmnet [state]
(let [pid (get-in state [:workspace :current])]
(update-in state [:workspace pid :drawing :segments] #(vec (butlast %)))))]
(update-in state [:workspace-local :drawing :segments] #(vec (butlast %))))]
(ptk/reify ::handle-drawing-path
ptk/WatchEvent
(watch [_ state stream]
(let [pid (get-in state [:workspace :current])
{:keys [zoom flags]} (get-in state [:workspace pid])
(let [{:keys [zoom flags]} (:workspace-local state)
align? (refs/alignment-activated? flags)
last-point (volatile! (gpt/divide @uws/mouse-position zoom))
@ -252,29 +242,23 @@
(and (uws/mouse-event? event) (= type :up))))
(initialize-drawing [state]
(let [pid (get-in state [:workspace :current])]
(assoc-in state [:workspace pid :drawing ::initialized?] true)))
(assoc-in state [:workspace-local :drawing ::initialized?] true))
(insert-point-segment [state point]
(let [pid (get-in state [:workspace :current])]
(update-in state [:workspace pid :drawing :segments] (fnil conj []) point)))
(update-in state [:workspace-local :drawing :segments] (fnil conj []) point))
(simplify-drawing-path [state tolerance]
(let [pid (get-in state [:workspace :current])]
(update-in state [:workspace pid :drawing :segments] path/simplify tolerance)))]
(update-in state [:workspace-local :drawing :segments] path/simplify tolerance))]
(ptk/reify ::handle-drawing-curve
ptk/WatchEvent
(watch [_ state stream]
(let [pid (get-in state [:workspace :current])
{:keys [zoom flags]} (get-in state [:workspace pid])
(let [{:keys [zoom flags]} (:workspace-local state)
align? (refs/alignment-activated? flags)
stoper (rx/filter stoper-event? stream)
mouse (->> (rx/sample 10 uws/mouse-position)
(rx/mapcat #(conditional-align % align?))
(rx/map #(gpt/divide % zoom)))]
(rx/concat
(rx/of initialize-drawing)
(->> mouse
@ -287,8 +271,7 @@
(ptk/reify ::handle-finish-drawing
ptk/WatchEvent
(watch [_ state stream]
(let [pid (get-in state [:workspace :current])
shape (get-in state [:workspace pid :drawing])]
(let [shape (get-in state [:workspace-local :drawing])]
(rx/concat
(rx/of dw/clear-drawing)
(when (::initialized? shape)
@ -305,8 +288,7 @@
(ptk/reify ::close-drawing-path
ptk/UpdateEvent
(update [_ state]
(let [pid (get-in state [:workspace :current])]
(assoc-in state [:workspace pid :drawing :close?] true)))))
(assoc-in state [:workspace-local :drawing :close?] true))))
;; --- Components

View file

@ -132,7 +132,7 @@
[:ul.options-btn
[:li.tooltip.tooltip-bottom.view-mode
{:alt (tr "header.view-mode")
:on-click #(st/emit! (dw/->OpenView (:id page)))
;; :on-click #(st/emit! (dw/->OpenView (:id page)))
}
i/play]]
[:& zoom-widget]]

View file

@ -72,7 +72,8 @@
(rx/map normalize-proportion-lock)
(rx/mapcat (partial resize shape))
(rx/take-until stoper))
(rx/of (dw/materialize-current-modifier-in-bulk ids))))))))
(rx/of (dw/materialize-current-modifier-in-bulk ids)
::dw/page-data-update)))))))
;; --- Controls (Component)
@ -221,21 +222,18 @@
[:& controls {:shape shape :zoom zoom :on-click on-click}]))
(mf/defc selection-handlers
[{:keys [wst] :as props}]
(let [shapes-map (mf/deref refs/shapes-by-id)
shapes (map #(get shapes-map %) (:selected wst))
edition (:edition wst)
zoom (:zoom wst 1)
[{:keys [selected edition zoom] :as props}]
(let [data (mf/deref refs/workspace-data)
shapes (map #(get-in data [:shapes-by-id %]) selected)
num (count shapes)
{:keys [id type] :as shape} (first shapes)]
(cond
(zero? num)
nil
(> num 1)
[:& multiple-selection-handlers {:shapes shapes
:selected (:selected wst)
:selected selected
:zoom zoom}]
(and (= type :text)

View file

@ -20,27 +20,27 @@
(mf/defc left-sidebar
{:wrap [mf/wrap-memo]}
[{:keys [flags page] :as props}]
[{:keys [layout page] :as props}]
[:aside.settings-bar.settings-bar-left
[:div.settings-bar-inside
(when (contains? flags :sitemap)
(when (contains? layout :sitemap)
[:& sitemap-toolbox {:project-id (:project-id page)
:current-page-id (:id page)
:page page}])
(when (contains? flags :document-history)
(when (contains? layout :document-history)
[:& history-toolbox])
(when (contains? flags :layers)
(when (contains? layout :layers)
[:& layers-toolbox {:page page}])]])
;; --- Right Sidebar (Component)
(mf/defc right-sidebar
[{:keys [flags page] :as props}]
[{:keys [layout page] :as props}]
[:aside#settings-bar.settings-bar
[:div.settings-bar-inside
(when (contains? flags :drawtools)
[:& draw-toolbox {:flags flags}])
(when (contains? flags :element-options)
(when (contains? layout :drawtools)
[:& draw-toolbox {:layout layout}])
(when (contains? layout :element-options)
[:& options-toolbox {:page page}])
#_(when (contains? flags :icons)
#_(when (contains? layout :icons)
(icons-toolbox))]])

View file

@ -78,6 +78,7 @@
(mf/defc layer-item
[{:keys [shape selected index] :as props}]
;; (prn "layer-item" index (:name shape))
(letfn [(toggle-blocking [event]
(dom/stop-propagation event)
(let [{:keys [id blocked]} shape]
@ -107,7 +108,7 @@
(dw/select-shape id)))))
(on-drop [item monitor]
(st/emit! (udp/persist-page (:page shape))))
(st/emit! ::dw/page-data-update))
(on-hover [item monitor]
(st/emit! (dw/change-shape-order {:id (:shape-id item)
@ -168,10 +169,9 @@
(dw/select-shape id)))))
(on-drop [item monitor]
(st/emit! (udp/persist-page (:page canvas))))
(st/emit! ::dw/page-data-update))
(on-hover [item monitor]
(prn "canvas-item$hover" (:id canvas))
(st/emit! (dw/change-canvas-order {:id (:canvas-id item)
:index index})))]
(let [selected? (contains? selected (:id canvas))
@ -236,21 +236,25 @@
;; --- Layers Toolbox
(mf/defc layers-toolbox
[{:keys [page selected] :as props}]
[{:keys [page] :as props}]
(let [on-click #(st/emit! (dw/toggle-flag :layers))
selected (mf/deref refs/selected-shapes)
shapes-by-id (mf/deref shapes-iref)
canvas (->> (:canvas page)
data (mf/deref refs/workspace-data)
shapes-by-id (:shapes-by-id data)
canvas (->> (:canvas data)
(map #(get shapes-by-id %))
(enumerate))
all-shapes (->> (:shapes page)
(map #(get shapes-by-id %)))
shapes (->> all-shapes
(filter #(not (:canvas %)))
(enumerate))
shapes (->> (:shapes data)
(map #(get shapes-by-id %)))
all-shapes (enumerate all-shapes)]
all-shapes (enumerate shapes)
unc-shapes (->> shapes
(filter #(nil? (:canvas %)))
(enumerate))]
[:div#layers.tool-window
[:div.tool-window-bar
@ -261,5 +265,5 @@
[:& canvas-list {:canvas canvas
:shapes all-shapes
:selected selected}]
[:& layers-list {:shapes shapes
[:& layers-list {:shapes unc-shapes
:selected selected}]]]))

View file

@ -11,7 +11,6 @@
[rumext.alpha :as mf]
[rumext.core :as mx]
[uxbox.builtins.icons :as i]
[uxbox.main.data.shapes :as uds]
[uxbox.main.data.workspace :as udw]
[uxbox.main.geom :as geom]
[uxbox.main.store :as st]

View file

@ -9,7 +9,6 @@
(:require
[rumext.alpha :as mf]
[uxbox.builtins.icons :as i]
[uxbox.main.data.shapes :as uds]
[uxbox.main.data.workspace :as udw]
[uxbox.main.geom :as geom]
[uxbox.main.store :as st]

View file

@ -9,7 +9,6 @@
(:require
[rumext.alpha :as mf]
[uxbox.builtins.icons :as i]
[uxbox.main.data.shapes :as uds]
[uxbox.main.data.workspace :as udw]
[uxbox.main.geom :as geom]
[uxbox.main.store :as st]

View file

@ -9,7 +9,6 @@
(:require
[rumext.alpha :as mf]
[uxbox.builtins.icons :as i]
[uxbox.main.data.shapes :as uds]
[uxbox.main.data.workspace :as udw]
[uxbox.main.geom :as geom]
[uxbox.main.store :as st]

View file

@ -11,7 +11,6 @@
[uxbox.main.store :as st]
[uxbox.main.geom :as geom]
[uxbox.main.data.workspace :as udw]
[uxbox.main.data.shapes :as uds]
[uxbox.builtins.icons :as i]
[uxbox.util.i18n :refer (tr)]
[uxbox.util.router :as r]

View file

@ -15,11 +15,12 @@
[uxbox.main.data.projects :as dp]
[uxbox.main.data.workspace :as dw]
[uxbox.main.store :as st]
[uxbox.main.refs :as refs]
[uxbox.main.ui.confirm :refer [confirm-dialog]]
[uxbox.main.ui.modal :as modal]
[uxbox.main.ui.workspace.sidebar.sitemap-forms :refer [page-form-dialog]]
[uxbox.main.ui.workspace.sortable :refer [use-sortable]]
[uxbox.util.data :refer [classnames]]
[uxbox.util.data :refer [classnames enumerate]]
[uxbox.util.dom :as dom]
[uxbox.util.i18n :refer [tr]]
[uxbox.util.router :as rt]))
@ -37,14 +38,12 @@
(dom/stop-propagation event)
(modal/show! confirm-dialog {:on-accept delete}))
(on-drop [item monitor]
(st/emit! (udp/rehash-pages (:project-id page))))
(prn "TODO"))
(on-hover [item monitor]
(st/emit! (udp/move-page {:project-id (:project-id item)
:page-id (:page-id item)
:index index})))]
(st/emit! (dw/change-page-order {:id (:id item)
:index index})))]
(let [[dprops ref] (use-sortable {:type "page-item"
:data {:page-id (:id page)
:project-id (:project-id page)
:data {:id (:id page)
:index index}
:on-hover on-hover
:on-drop on-drop})]
@ -64,40 +63,52 @@
(when deletable?
[:a {:on-click on-delete} i/trash])]]])))
;; --- Pages List
(defn- make-pages-iref
[{:keys [id pages] :as project}]
(-> (l/lens (fn [s] (into [] (map #(get-in s [:pages %])) pages)))
(l/derive st/state {:equals? =})))
;; --- Page Item Wrapper
(def ^:private pages-map-iref
(-> (l/key :pages)
(defn- make-page-ref
[page-id]
(-> (l/in [:pages page-id])
(l/derive st/state)))
(mf/defc page-item-wrapper
[{:keys [page-id index deletable? selected?] :as props}]
(let [page-ref (mf/use-memo {:deps #js [page-id]
:fn #(make-page-ref page-id)})
page (mf/deref page-ref)]
[:& page-item {:page page
:index index
:deletable? deletable?
:selected? selected?}]))
;; --- Pages List
(mf/defc pages-list
[{:keys [project current-page-id] :as props}]
(let [pages-map (mf/deref pages-map-iref)
pages (->> (vals pages-map)
(filter #(= (:project-id %) (:id project))))
(let [pages (enumerate (:pages project))
deletable? (> (count pages) 1)]
[:ul.element-list
(for [[index item] (map-indexed vector pages)]
[:& page-item {:page item
:index index
:deletable? deletable?
:selected? (= (:id item) current-page-id)
:key (:id item)}])]))
(for [[index page-id] pages]
[:& page-item-wrapper
{:page-id page-id
:index index
:deletable? deletable?
:selected? (= page-id current-page-id)
:key page-id}])]))
;; --- Sitemap Toolbox
(def ^:private workspace-project
(letfn [(selector [state]
(let [project-id (get-in state [:workspace-page :project-id])]
(get-in state [:projects project-id])))]
(-> (l/lens selector)
(l/derive st/state))))
(mf/defc sitemap-toolbox
[{:keys [project-id current-page-id] :as props}]
(let [project-iref (mf/use-memo {:deps #js [project-id]
:fn #(-> (l/in [:projects project-id])
(l/derive st/state))})
project (mf/deref project-iref)
create #(modal/show! page-form-dialog {:page {:project project-id}})
(let [project (mf/deref workspace-project)
create #(modal/show! page-form-dialog {:page {:project-id project-id}})
close #(st/emit! (dw/toggle-flag :sitemap))]
[:div.sitemap.tool-window
[:div.tool-window-bar

View file

@ -12,6 +12,7 @@
[uxbox.builtins.icons :as i]
[uxbox.main.constants :as c]
[uxbox.main.data.pages :as udp]
[uxbox.main.data.workspace :as udw]
[uxbox.main.store :as st]
[uxbox.main.ui.modal :as modal]
[uxbox.util.dom :as dom]
@ -20,22 +21,12 @@
[uxbox.util.i18n :refer [tr]]))
(s/def ::id ::us/uuid)
(s/def ::project ::us/uuid)
(s/def ::project-id ::us/uuid)
(s/def ::name ::us/not-empty-string)
(s/def ::width ::us/number-str)
(s/def ::height ::us/number-str)
(s/def ::page-form
(s/keys :req-un [::id
::project
::name
::width
::height]))
(def defaults
{:name ""
:width "1366"
:height "768"})
(s/keys :req-un [::project-id ::name]
:opt-un [::id]))
(defn- on-submit
[event form]
@ -43,20 +34,13 @@
(modal/hide!)
(let [data (:clean-data form)]
(if (nil? (:id data))
(st/emit! (udp/form->create-page data))
(st/emit! (udp/form->update-page data)))))
(defn- swap-size
[event {:keys [data] :as form}]
(swap! data assoc
:width (:height data)
:height (:width data)))
(st/emit! (udp/create-page data))
(st/emit! (udp/rename-page data)))))
(defn- initial-data
[page]
(merge {:name "" :width "1366" :height "768"}
(select-keys page [:name :id :project])
(select-keys (:metadata page) [:width :height])))
(merge {:name ""}
(select-keys page [:name :id :project-id])))
(mf/defc page-form
[{:keys [page] :as props}]
@ -71,32 +55,6 @@
:on-change (fm/on-input-change form :name)
:value (:name data)
:auto-focus true}]
[:div.project-size
[:div.input-element.pixels
[:span (tr "ds.width")]
[:input#project-witdh.input-text
{:placeholder (tr "ds.width")
:name "width"
:type "number"
:min 0
:max 5000
:class (fm/error-class form :width)
:on-blur (fm/on-input-blur form :width)
:on-change (fm/on-input-change form :width)
:value (:width data)}]]
[:a.toggle-layout {:on-click #(swap-size % form)} i/toggle]
[:div.input-element.pixels
[:span (tr "ds.height")]
[:input#project-height.input-text
{:placeholder (tr "ds.height")
:name "height"
:type "number"
:min 0
:max 5000
:class (fm/error-class form :height)
:on-blur (fm/on-input-blur form :height)
:on-change (fm/on-input-change form :height)
:value (:height data)}]]]
[:input.btn-primary
{:value (tr "ds.go")
:type "submit"

View file

@ -22,7 +22,7 @@
[uxbox.main.ui.workspace.streams :as uws]
[uxbox.main.ui.workspace.drawarea :refer [start-drawing]]
[uxbox.main.ui.shapes :as uus]
[uxbox.main.ui.shapes :refer [shape-wrapper]]
[uxbox.main.ui.workspace.drawarea :refer [draw-area]]
[uxbox.main.ui.workspace.selection :refer [selection-handlers]]
@ -74,17 +74,15 @@
(def ^:private handle-selrect
(letfn [(update-state [state position]
(let [id (get-in state [:workspace :current])
selrect (get-in state [:workspace id :selrect])]
(let [selrect (get-in state [:workspace-local :selrect])]
(if selrect
(assoc-in state [:workspace id :selrect]
(assoc-in state [:workspace-local :selrect]
(dw/selection->rect (assoc selrect :stop position)))
(assoc-in state [:workspace id :selrect]
(assoc-in state [:workspace-local :selrect]
(dw/selection->rect {:start position :stop position})))))
(clear-state [state]
(let [id (get-in state [:workspace :current])]
(update-in state [:workspace id] dissoc :selrect)))]
(update state :workspace-local dissoc :selrect))]
(ptk/reify ::handle-selrect
ptk/WatchEvent
(watch [_ state stream]
@ -129,11 +127,28 @@
;; --- Viewport
(mf/defc canvas-and-shapes
{:wrap [mf/wrap-memo]}
[props]
(let [data (mf/deref refs/workspace-data)
shapes-by-id (:shapes-by-id data)
shapes (map #(get shapes-by-id %) (:shapes data []))
canvas (map #(get shapes-by-id %) (:canvas data []))]
[:*
(for [item canvas]
[:& shape-wrapper {:shape item :key (:id item)}])
(for [item (reverse shapes)]
[:& shape-wrapper {:shape item :key (:id item)}])]))
(mf/defc viewport
[{:keys [page] :as props}]
(let [{:keys [drawing-tool tooltip zoom flags edition] :as wst} (mf/deref refs/workspace)
(let [{:keys [drawing-tool
zoom
flags
edition
selected]
:as local} (mf/deref refs/workspace-local)
viewport-ref (mf/use-ref nil)
tooltip (or tooltip (get-shape-tooltip drawing-tool))
zoom (or zoom 1)]
(letfn [(on-mouse-down [event]
(dom/stop-propagation event)
@ -230,9 +245,6 @@
;; (prn "viewport$render")
[:*
[:& coordinates {:zoom zoom}]
#_[:div.tooltip-container
(when tooltip
[:& cursor-tooltip {:tooltip tooltip}])]
[:svg.viewport {:width (* c/viewport-width zoom)
:height (* c/viewport-height zoom)
:ref viewport-ref
@ -244,23 +256,23 @@
:on-mouse-down on-mouse-down
:on-mouse-up on-mouse-up}
[:g.zoom {:transform (str "scale(" zoom ", " zoom ")")}
(when page
[:*
[:& uus/canvas-and-shapes {:page page}]
(when (seq (:selected wst))
[:& selection-handlers {:wst wst}])
(when-let [dshape (:drawing wst)]
[:& draw-area {:shape dshape
:zoom (:zoom wst)
:modifiers (:modifiers wst)}])])
[:*
[:& canvas-and-shapes]
(when (seq selected)
[:& selection-handlers {:selected selected
:zoom zoom
:edition edition}])
(when-let [drawing-shape (:drawing local)]
[:& draw-area {:shape drawing-shape
:zoom zoom
:modifiers (:modifiers local)}])]
(if (contains? flags :grid)
[:& grid {:page page}])]
(when (contains? flags :ruler)
[:& ruler {:zoom zoom :ruler (:ruler wst)}])
[:& selrect {:data (:selrect wst)}]]])))
(when (contains? flags :ruler)
[:& ruler {:zoom zoom :ruler (:ruler local)}])
[:& selrect {:data (:selrect local)}]]])))