diff --git a/frontend/uxbox/core.cljs b/frontend/uxbox/core.cljs index 131db1b9c..2c48c1f21 100644 --- a/frontend/uxbox/core.cljs +++ b/frontend/uxbox/core.cljs @@ -16,4 +16,5 @@ (println "BOOTSTRAP") (ui/init) (rs/emit! (dl/load-data)) - (rx/on-value s/stream #(dl/persist-state %)))) + (rx/on-value s/stream #(dl/persist-state %)) + 1)) diff --git a/frontend/uxbox/data/workspace.cljs b/frontend/uxbox/data/workspace.cljs index 9c010f73e..4269fa4d0 100644 --- a/frontend/uxbox/data/workspace.cljs +++ b/frontend/uxbox/data/workspace.cljs @@ -15,9 +15,20 @@ (reify rs/UpdateEvent (-apply-update [_ state] - (println "KAKAKA" (get-in state [:workspace :visible-pagebar])) - (update-in state [:workspace :visible-pagebar] (fnil not false))) + (update-in state [:workspace :pagesbar-enabled] (fnil not false))) IPrintWithWriter (-pr-writer [mv writer _] (-write writer "#")))) + +(defn toggle-grid + [] + (reify + rs/UpdateEvent + (-apply-update [_ state] + (println "toggle-grid") + (update-in state [:workspace :grid-enabled] (fnil not false))) + + IPrintWithWriter + (-pr-writer [mv writer _] + (-write writer "#")))) diff --git a/frontend/uxbox/ui/workspace.cljs b/frontend/uxbox/ui/workspace.cljs index 5440a763a..0b7e5c0c8 100644 --- a/frontend/uxbox/ui/workspace.cljs +++ b/frontend/uxbox/ui/workspace.cljs @@ -16,6 +16,7 @@ (defn workspace-render [own projectid] + (println "workspace-render") (html [:div (wb/header) @@ -30,7 +31,7 @@ (wr/v-rule) ;; Canvas - ;; (wa/working-area) + (wa/workarea) ;; (working-area conn @open-toolboxes page project shapes (rum/react ws/zoom) (rum/react ws/grid?)) ;; ;; Aside ;; (when-not (empty? @open-toolboxes) diff --git a/frontend/uxbox/ui/workspace/base.cljs b/frontend/uxbox/ui/workspace/base.cljs index 587e14512..ec58d966f 100644 --- a/frontend/uxbox/ui/workspace/base.cljs +++ b/frontend/uxbox/ui/workspace/base.cljs @@ -39,7 +39,6 @@ (as-> (l/in [:workspace]) $ (l/focus-atom $ s/state))) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Streams ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -51,6 +50,16 @@ (defonce top-scroll (rx/to-atom top-scroll-s)) (defonce left-scroll (rx/to-atom left-scroll-s)) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Constants +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(def viewport-height 3000) +(def viewport-width 3000) + +(def document-start-x 50) +(def document-start-y 50) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Header ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -67,49 +76,52 @@ (defn header-render [own] - (let [page (rum/react page-state) - toggle #(rs/emit! (dw/toggle-pagesbar))] - (html - [:header#workspace-bar.workspace-bar - [:div.main-icon - (nav/link (r/route-for :dashboard/projects) i/logo-icon)] - [:div.project-tree-btn - {:on-click toggle} - i/project-tree - [:span (:name page)]] - [:div.workspace-options - [:ul.options-btn - [:li.tooltip.tooltip-bottom {:alt "Undo (Ctrl + Z)"} - i/undo] - [:li.tooltip.tooltip-bottom {:alt "Redo (Ctrl + Shift + Z)"} - i/redo]] - [:ul.options-btn - ;; TODO: refactor - [:li.tooltip.tooltip-bottom - {:alt "Export (Ctrl + E)"} - ;; page-title - [:a {:download (str (:name page) ".svg") - :href "#" :on-click on-download-clicked} - i/export]] - [:li.tooltip.tooltip-bottom - {:alt "Image (Ctrl + I)"} - i/image]] - [:ul.options-btn - [:li.tooltip.tooltip-bottom - {:alt "Ruler (Ctrl + R)"} - i/ruler] - [:li.tooltip.tooltip-bottom - {:alt "Grid (Ctrl + G)" - :class (when false "selected") - :on-click (constantly nil)} - i/grid] - [:li.tooltip.tooltip-bottom - {:alt "Align (Ctrl + A)"} - i/alignment] - [:li.tooltip.tooltip-bottom - {:alt "Organize (Ctrl + O)"} - i/organize]]] - (ui.u/user)]))) + (letfn [(toggle-pagesbar [e] + (rs/emit! (dw/toggle-pagesbar))) + (toggle-grid [e] + (rs/emit! (dw/toggle-grid)))] + (let [page (rum/react page-state)] + (html + [:header#workspace-bar.workspace-bar + [:div.main-icon + (nav/link (r/route-for :dashboard/projects) i/logo-icon)] + [:div.project-tree-btn + {:on-click toggle-pagesbar} + i/project-tree + [:span (:name page)]] + [:div.workspace-options + [:ul.options-btn + [:li.tooltip.tooltip-bottom {:alt "Undo (Ctrl + Z)"} + i/undo] + [:li.tooltip.tooltip-bottom {:alt "Redo (Ctrl + Shift + Z)"} + i/redo]] + [:ul.options-btn + ;; TODO: refactor + [:li.tooltip.tooltip-bottom + {:alt "Export (Ctrl + E)"} + ;; page-title + [:a {:download (str (:name page) ".svg") + :href "#" :on-click on-download-clicked} + i/export]] + [:li.tooltip.tooltip-bottom + {:alt "Image (Ctrl + I)"} + i/image]] + [:ul.options-btn + [:li.tooltip.tooltip-bottom + {:alt "Ruler (Ctrl + R)"} + i/ruler] + [:li.tooltip.tooltip-bottom + {:alt "Grid (Ctrl + G)" + :class (when false "selected") + :on-click toggle-grid} + i/grid] + [:li.tooltip.tooltip-bottom + {:alt "Align (Ctrl + A)"} + i/alignment] + [:li.tooltip.tooltip-bottom + {:alt "Organize (Ctrl + O)"} + i/organize]]] + (ui.u/user)])))) (def header (util/component @@ -272,7 +284,7 @@ project (rum/react project-state)] (html [:div#project-bar.project-bar - (when-not (:visible-pagebar workspace false) + (when-not (:pagesbar-enabled workspace false) {:class "toggle"}) (if (:edit @local) (project-sidebar-form local) diff --git a/frontend/uxbox/ui/workspace/workarea.cljs b/frontend/uxbox/ui/workspace/workarea.cljs index 60c8cc25b..7ae4402d5 100644 --- a/frontend/uxbox/ui/workspace/workarea.cljs +++ b/frontend/uxbox/ui/workspace/workarea.cljs @@ -14,7 +14,7 @@ ;; Coordinates Debug ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defonce canvas-coordinates (atom {})) +(defonce canvas-coordinates (atom [1 1])) (defn coordenates-render [] @@ -23,12 +23,13 @@ [:div {:style {:position "absolute" :left "80px" :top "20px"}} [:table - [:tr - [:td "X:"] - [:td (or x 1)]] - [:tr - [:td "Y:"] - [:td y]]]]))) + [:tbody + [:tr + [:td "X:"] + [:td x]] + [:tr + [:td "Y:"] + [:td y]]]]]))) (def coordinates (util/component @@ -46,7 +47,179 @@ (util/component {:render background-render :name "background" - :mixins [rum/static]})) + :mixins [util/static]})) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Grid +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(def ^:static grid-color "#cccccc") + +(defn grid-render + [own enabled? width height start-width start-height zoom] + (println "grid-render") + (letfn [(vertical-line [position value padding] + (let [ticks-mod (/ 100 zoom) + step-size (/ 10 zoom)] + (if (< (mod value ticks-mod) step-size) + (html [:line {:key position + :y1 padding + :y2 width + :x1 position + :x2 position + :stroke grid-color + :stroke-width (/ 0.5 zoom) + :opacity 0.75}]) + (html [:line {:key position + :y1 padding + :y2 width + :x1 position + :x2 position + :stroke grid-color + :stroke-width (/ 0.5 zoom) + :opacity 0.25}])))) + (horizontal-line [position value padding] + (let [ticks-mod (/ 100 zoom) + step-size (/ 10 zoom)] + (if (< (mod value ticks-mod) step-size) + (html [:line {:key position + :y1 position + :y2 position + :x1 padding + :x2 height + :stroke grid-color + :stroke-width (/ 0.5 zoom) + :opacity 0.75}]) + (html [:line {:key position + :y1 position + :y2 position + :x1 padding + :x2 height + :stroke grid-color + :stroke-width (/ 0.5 zoom) + :opacity 0.25}]))))] + (let [padding (* 20 zoom) + ticks-mod (/ 100 zoom) + step-size (/ 10 zoom) + vertical-ticks (range (- padding start-height) + (- height start-height padding) step-size) + horizontal-ticks (range (- padding start-width) + (- width start-width padding) step-size)] + (html + [:g.grid + {:style {:display (if enabled? "block" "none")}} + (for [tick vertical-ticks] + (let [position (+ tick start-width) + line (vertical-line position tick padding)] + (rum/with-key line (str "tick-" tick)))) + (for [tick horizontal-ticks] + (let [position (+ tick start-height) + line (horizontal-line position tick padding)] + (rum/with-key line (str "tick-" tick))))])))) + + +(def grid + (util/component + {:render grid-render + :name "grid" + :mixins [util/static]})) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Canvas +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; (rum/defc canvas < rum/reactive +;; shapes-push-mixin +;; (mx/cmds-mixin +;; [::draw draw! (fn [[conn page] shape] +;; (actions/draw-shape conn page shape))] + +;; [::move move! (fn [[conn] selections] +;; (actions/update-shapes conn selections))]) +;; [conn +;; page +;; shapes +;; {:keys [viewport-height +;; viewport-width +;; document-start-x +;; document-start-y]}] + +(defn canvas-render + [] + (let [page (rum/react wb/page-state) + page-width (:width page) + page-height (:height page) + ;; selection-uuids (rum/react selected-ids) + ;; selected-shapes (rum/react selected-shapes) + ;; raw-shapes (into [] + ;; (comp + ;; (filter :shape/visible?) + ;; (filter #(not (contains? selection-uuids (:shape/uuid %)))) + ;; (map :shape/data)) + ;; shapes) + ] + (html + [:svg#page-canvas + {:x wb/document-start-x + :y wb/document-start-y + :width page-width + :height page-height + ;; :on-mouse-down cs/on-mouse-down + ;; :on-mouse-up cs/on-mouse-up + } + (background) + #_(apply vector :svg#page-layout (map shapes/shape->svg raw-shapes)) + #_(when-let [shape (rum/react drawing)] + (shapes/shape->drawing-svg shape)) + #_(when-not (empty? selected-shapes) + (let [rs selected-shapes] + (vec (cons :g + (concat + (map shapes/shape->selected-svg rs) + (map shapes/shape->svg rs))))))]))) + +(def canvas + (util/component + {:render canvas-render + :name "canvas" + :mixins [rum/reactive]})) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Viewport +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defn viewport-render + [] + (let [workspace (rum/react wb/workspace-state) + zoom 1] + (println "viewport-render" (:grid-enabled workspace true)) + (html + [:svg#viewport + {:width wb/viewport-height + :height wb/viewport-width} + [:g.zoom + {:transform (str "scale(" zoom ", " zoom ")")} + (canvas) + #_(canvas conn + page + shapes + {:viewport-height wb/viewport-height + :viewport-width wb/viewport-width + :document-start-x wb/document-start-x + :document-start-y wb/document-start-y}) + (grid (:grid-enabled workspace true) + wb/viewport-width + wb/viewport-height + wb/document-start-x + wb/document-start-y + zoom)]]))) + +(def viewport + (util/component + {:render viewport-render + :name "viewport" + :mixins [rum/reactive]})) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Work Area @@ -54,8 +227,10 @@ (defn working-area-render [own] + (println "working-area-render") (html [:section.workspace-canvas + {:class "no-tool-bar"} #_{:class (when (empty? open-setting-boxes) "no-tool-bar") :on-scroll (constantly nil)} @@ -66,11 +241,11 @@ zoom-cursor shapes-cursor)) (coordinates) - #_(viewport conn page shapes zoom grid?)])) + (viewport)])) -(def working-area +(def workarea (util/component {:render working-area-render - :name "working-area" + :name "workarea" :mixins []})) diff --git a/frontend/uxbox/util.cljs b/frontend/uxbox/util.cljs index 942dcce30..0ed46eeed 100644 --- a/frontend/uxbox/util.cljs +++ b/frontend/uxbox/util.cljs @@ -111,6 +111,12 @@ (assoc state key local-state))) })) + +(def static + {:should-update + (fn [old-state new-state] + (not= (:rum/props old-state) (:rum/props new-state)))}) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Lenses & Helpers ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;