mirror of
https://github.com/penpot/penpot.git
synced 2025-06-12 21:41:39 +02:00
feat(frontend): refactor many workspace components (rumext update)
This commit is contained in:
parent
c4d7d545ae
commit
9ddd9f317d
15 changed files with 504 additions and 526 deletions
|
@ -2,78 +2,42 @@
|
||||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
;;
|
;;
|
||||||
;; Copyright (c) 2015-2017 Andrey Antukh <niwi@niwi.nz>
|
|
||||||
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||||
|
;; Copyright (c) 2015-2019 Andrey Antukh <niwi@niwi.nz>
|
||||||
|
|
||||||
(ns uxbox.main.ui.workspace
|
(ns uxbox.main.ui.workspace
|
||||||
(:require [beicon.core :as rx]
|
(:require
|
||||||
[lentes.core :as l]
|
[beicon.core :as rx]
|
||||||
[uxbox.main.store :as st]
|
[lentes.core :as l]
|
||||||
[uxbox.main.constants :as c]
|
[rumext.core :as mx :include-macros true]
|
||||||
[uxbox.main.refs :as refs]
|
[uxbox.main.constants :as c]
|
||||||
[uxbox.main.streams :as streams]
|
[uxbox.main.data.history :as udh]
|
||||||
[uxbox.main.data.workspace :as dw]
|
[uxbox.main.data.pages :as udp]
|
||||||
[uxbox.main.data.pages :as udp]
|
[uxbox.main.data.undo :as udu]
|
||||||
[uxbox.main.data.history :as udh]
|
[uxbox.main.data.workspace :as dw]
|
||||||
[uxbox.main.data.undo :as udu]
|
[uxbox.main.refs :as refs]
|
||||||
[uxbox.main.user-events :as uev]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.main.ui.messages :refer [messages-widget]]
|
[uxbox.main.streams :as streams]
|
||||||
[uxbox.main.ui.confirm]
|
[uxbox.main.ui.confirm]
|
||||||
[uxbox.main.ui.workspace.images]
|
[uxbox.main.ui.keyboard :as kbd]
|
||||||
[uxbox.main.ui.keyboard :as kbd]
|
[uxbox.main.ui.messages :refer [messages-widget]]
|
||||||
[uxbox.main.ui.workspace.scroll :as scroll]
|
[uxbox.main.ui.workspace.canvas :refer [viewport]]
|
||||||
[uxbox.main.ui.workspace.download]
|
[uxbox.main.ui.workspace.colorpalette :refer [colorpalette]]
|
||||||
[uxbox.main.ui.workspace.shortcuts :refer [shortcuts-mixin]]
|
[uxbox.main.ui.workspace.download]
|
||||||
[uxbox.main.ui.workspace.header :refer [header]]
|
[uxbox.main.ui.workspace.header :refer [header]]
|
||||||
[uxbox.main.ui.workspace.rules :refer [horizontal-rule vertical-rule]]
|
[uxbox.main.ui.workspace.images]
|
||||||
[uxbox.main.ui.workspace.sidebar.history :refer [history-dialog]]
|
[uxbox.main.ui.workspace.rules :refer [horizontal-rule vertical-rule]]
|
||||||
[uxbox.main.ui.workspace.sidebar :refer [left-sidebar right-sidebar]]
|
[uxbox.main.ui.workspace.scroll :as scroll]
|
||||||
[uxbox.main.ui.workspace.colorpalette :refer [colorpalette]]
|
[uxbox.main.ui.workspace.shortcuts :refer [shortcuts-mixin]]
|
||||||
[uxbox.main.ui.workspace.canvas :refer [viewport]]
|
[uxbox.main.ui.workspace.sidebar :refer [left-sidebar right-sidebar]]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.main.ui.workspace.sidebar.history :refer [history-dialog]]
|
||||||
[uxbox.util.geom.point :as gpt]
|
[uxbox.main.user-events :as uev]
|
||||||
[uxbox.util.data :refer [classnames]]
|
[uxbox.util.data :refer [classnames]]
|
||||||
[rumext.core :as mx :include-macros true]))
|
[uxbox.util.dom :as dom]
|
||||||
|
[uxbox.util.geom.point :as gpt]))
|
||||||
|
|
||||||
;; --- Workspace
|
;; --- Workspace
|
||||||
|
|
||||||
(defn- workspace-will-mount
|
|
||||||
[own]
|
|
||||||
(let [[projectid pageid] (:rum/args own)]
|
|
||||||
(st/emit! (dw/initialize projectid pageid))
|
|
||||||
own))
|
|
||||||
|
|
||||||
(defn- workspace-did-mount
|
|
||||||
[own]
|
|
||||||
(let [[projectid pageid] (:rum/args own)
|
|
||||||
dom (mx/ref-node own "workspace-canvas")
|
|
||||||
scroll-to-page-center #(scroll/scroll-to-page-center dom @refs/selected-page)
|
|
||||||
sub (rx/subscribe streams/page-id-ref-s scroll-to-page-center)]
|
|
||||||
|
|
||||||
(scroll-to-page-center)
|
|
||||||
|
|
||||||
(st/emit! (udp/watch-page-changes pageid)
|
|
||||||
(udu/watch-page-changes pageid))
|
|
||||||
|
|
||||||
(assoc own ::sub sub)))
|
|
||||||
|
|
||||||
(defn- workspace-will-unmount
|
|
||||||
[own]
|
|
||||||
(st/emit! ::udp/stop-page-watcher)
|
|
||||||
(rx/cancel! (::sub own))
|
|
||||||
(dissoc own ::sub))
|
|
||||||
|
|
||||||
(defn- workspace-did-remount
|
|
||||||
[old-state state]
|
|
||||||
(let [[projectid pageid] (:rum/args state)
|
|
||||||
[oldprojectid oldpageid] (:rum/args old-state)]
|
|
||||||
(when (not= pageid oldpageid)
|
|
||||||
(st/emit! (dw/initialize projectid pageid)
|
|
||||||
::udp/stop-page-watcher
|
|
||||||
(udp/watch-page-changes pageid)
|
|
||||||
(udu/watch-page-changes pageid)))
|
|
||||||
state))
|
|
||||||
|
|
||||||
(defn- on-scroll
|
(defn- on-scroll
|
||||||
[event]
|
[event]
|
||||||
(let [target (.-target event)
|
(let [target (.-target event)
|
||||||
|
@ -99,52 +63,76 @@
|
||||||
(-> (l/key :page)
|
(-> (l/key :page)
|
||||||
(l/derive refs/workspace)))
|
(l/derive refs/workspace)))
|
||||||
|
|
||||||
(mx/defcs workspace
|
(mx/def workspace
|
||||||
{:did-remount workspace-did-remount
|
:key-fn vector
|
||||||
:will-mount workspace-will-mount
|
:mixins #{mx/static
|
||||||
:will-unmount workspace-will-unmount
|
|
||||||
:did-mount workspace-did-mount
|
|
||||||
:mixins [mx/static
|
|
||||||
mx/reactive
|
mx/reactive
|
||||||
shortcuts-mixin]}
|
shortcuts-mixin}
|
||||||
[own project-id page-id]
|
|
||||||
(let [flags (mx/react refs/flags)
|
|
||||||
left-sidebar? (not (empty? (keep flags [:layers :sitemap
|
|
||||||
:document-history])))
|
|
||||||
right-sidebar? (not (empty? (keep flags [:icons :drawtools
|
|
||||||
:element-options])))
|
|
||||||
classes (classnames
|
|
||||||
:no-tool-bar-right (not right-sidebar?)
|
|
||||||
:no-tool-bar-left (not left-sidebar?)
|
|
||||||
:scrolling (:viewport-positionig workspace))]
|
|
||||||
[:div {}
|
|
||||||
(messages-widget)
|
|
||||||
(header)
|
|
||||||
(colorpalette)
|
|
||||||
|
|
||||||
[:main.main-content {}
|
:init
|
||||||
[:section.workspace-content
|
(fn [own {:keys [project page] :as props}]
|
||||||
{:class classes
|
(st/emit! (dw/initialize project page))
|
||||||
:on-scroll on-scroll
|
(assoc own ::canvas (mx/create-ref)))
|
||||||
:on-wheel (partial on-wheel own)}
|
|
||||||
|
|
||||||
(history-dialog)
|
:did-mount
|
||||||
|
(fn [own]
|
||||||
|
(let [{:keys [project page]} (::mx/props own)
|
||||||
|
;; dom (mx/ref-node own "workspace-canvas")
|
||||||
|
dom (mx/ref-node (::canvas own))
|
||||||
|
scroll-to-page-center #(scroll/scroll-to-page-center dom @refs/selected-page)
|
||||||
|
sub (rx/subscribe streams/page-id-ref-s scroll-to-page-center)]
|
||||||
|
(scroll-to-page-center)
|
||||||
|
(st/emit! (udp/watch-page-changes page)
|
||||||
|
(udu/watch-page-changes page))
|
||||||
|
(assoc own ::sub sub)))
|
||||||
|
|
||||||
;; Rules
|
:will-unmount
|
||||||
(when (contains? flags :rules)
|
(fn [own]
|
||||||
(horizontal-rule))
|
(st/emit! ::udp/stop-page-watcher)
|
||||||
|
(rx/cancel! (::sub own))
|
||||||
|
(dissoc own ::sub))
|
||||||
|
|
||||||
(when (contains? flags :rules)
|
:render
|
||||||
(vertical-rule))
|
(fn [own props]
|
||||||
|
;; [own project-id page-id]
|
||||||
|
(let [flags (mx/react refs/flags)
|
||||||
|
project-id (get-in own [::mx/props :project])
|
||||||
|
page-id (get-in own [::mx/props :page])
|
||||||
|
left-sidebar? (not (empty? (keep flags [:layers :sitemap
|
||||||
|
:document-history])))
|
||||||
|
right-sidebar? (not (empty? (keep flags [:icons :drawtools
|
||||||
|
:element-options])))
|
||||||
|
classes (classnames
|
||||||
|
:no-tool-bar-right (not right-sidebar?)
|
||||||
|
:no-tool-bar-left (not left-sidebar?)
|
||||||
|
:scrolling (:viewport-positionig workspace))]
|
||||||
|
[:*
|
||||||
|
(messages-widget)
|
||||||
|
(header)
|
||||||
|
(colorpalette)
|
||||||
|
|
||||||
;; Canvas
|
[:main.main-content
|
||||||
[:section.workspace-canvas
|
[:section.workspace-content
|
||||||
{:id "workspace-canvas"
|
{:class classes
|
||||||
:ref "workspace-canvas"}
|
:on-scroll on-scroll
|
||||||
(viewport)]]
|
:on-wheel (partial on-wheel own)}
|
||||||
|
|
||||||
;; Aside
|
(history-dialog)
|
||||||
(when left-sidebar?
|
|
||||||
(left-sidebar flags page-id))
|
;; Rules
|
||||||
(when right-sidebar?
|
(when (contains? flags :rules)
|
||||||
(right-sidebar flags page-id))]]))
|
(horizontal-rule))
|
||||||
|
|
||||||
|
(when (contains? flags :rules)
|
||||||
|
(vertical-rule))
|
||||||
|
|
||||||
|
;; Canvas
|
||||||
|
[:section.workspace-canvas {:id "workspace-canvas"
|
||||||
|
:ref (::canvas own)}
|
||||||
|
(viewport)]]
|
||||||
|
|
||||||
|
;; Aside
|
||||||
|
(when left-sidebar?
|
||||||
|
(left-sidebar {:flags flags :page-id page-id}))
|
||||||
|
(when right-sidebar?
|
||||||
|
(right-sidebar {:flags flags :page-id page-id}))]])))
|
||||||
|
|
|
@ -244,7 +244,7 @@
|
||||||
opts {:shift? shift?
|
opts {:shift? shift?
|
||||||
:ctrl? ctrl?}]
|
:ctrl? ctrl?}]
|
||||||
(st/emit! (uev/mouse-event :double-click ctrl? shift?))))]
|
(st/emit! (uev/mouse-event :double-click ctrl? shift?))))]
|
||||||
[:div {}
|
[:*
|
||||||
(coordinates)
|
(coordinates)
|
||||||
[:div.tooltip-container {}
|
[:div.tooltip-container {}
|
||||||
(when tooltip
|
(when tooltip
|
||||||
|
|
|
@ -30,13 +30,13 @@
|
||||||
(on-close [event]
|
(on-close [event]
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(udl/close!))]
|
(udl/close!))]
|
||||||
[:div.lightbox-body.clipboard {}
|
[:div.lightbox-body.clipboard
|
||||||
[:div.clipboard-list {}
|
[:div.clipboard-list
|
||||||
(for [item (mx/react clipboard-ref)]
|
(for [item (mx/react clipboard-ref)]
|
||||||
[:div.clipboard-item
|
[:div.clipboard-item
|
||||||
{:key (str (:id item))
|
{:key (str (:id item))
|
||||||
:on-click (partial on-paste item)}
|
:on-click (partial on-paste item)}
|
||||||
[:span.clipboard-icon {} i/box]
|
[:span.clipboard-icon i/box]
|
||||||
[:span {} (str "Copied (" (dt/timeago (:created-at item)) ")")]])]
|
[:span {} (str "Copied (" (dt/timeago (:created-at item)) ")")]])]
|
||||||
[:a.close {:href "#" :on-click on-close} i/close]]))
|
[:a.close {:href "#" :on-click on-close} i/close]]))
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
[:span.color-text {} rgb-color]])))
|
[:span.color-text {} rgb-color]])))
|
||||||
|
|
||||||
(defn- palette-after-render
|
(defn- palette-after-render
|
||||||
[{:keys [rum/local] :as own}]
|
[{:keys [::mx/local] :as own}]
|
||||||
(let [dom (mx/ref-node own "container")
|
(let [dom (mx/ref-node own "container")
|
||||||
width (.-clientWidth dom)]
|
width (.-clientWidth dom)]
|
||||||
(when (not= (:width @local) width)
|
(when (not= (:width @local) width)
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
(mx/defcs palette
|
(mx/defcs palette
|
||||||
{:mixins [mx/static mx/reactive (mx/local)]
|
{:mixins [mx/static mx/reactive (mx/local)]
|
||||||
:after-render palette-after-render}
|
:after-render palette-after-render}
|
||||||
[{:keys [rum/local] :as own}]
|
[{:keys [::mx/local] :as own}]
|
||||||
(let [collections (->> (mx/react collections-ref)
|
(let [collections (->> (mx/react collections-ref)
|
||||||
(vals)
|
(vals)
|
||||||
(filter :id)
|
(filter :id)
|
||||||
|
@ -112,14 +112,14 @@
|
||||||
[:span.close-palette {:on-click close}
|
[:span.close-palette {:on-click close}
|
||||||
i/close]])))
|
i/close]])))
|
||||||
|
|
||||||
(defn- colorpalette-will-mount
|
(defn- colorpalette-init
|
||||||
[own]
|
[own]
|
||||||
(st/emit! (dc/fetch-collections))
|
(st/emit! (dc/fetch-collections))
|
||||||
own)
|
own)
|
||||||
|
|
||||||
(mx/defc colorpalette
|
(mx/defc colorpalette
|
||||||
{:mixins [mx/static mx/reactive]
|
{:mixins [mx/static mx/reactive]
|
||||||
:will-mount colorpalette-will-mount}
|
:init colorpalette-init}
|
||||||
[]
|
[]
|
||||||
(let [flags (mx/react refs/flags)]
|
(let [flags (mx/react refs/flags)]
|
||||||
(when (contains? flags :colorpalette)
|
(when (contains? flags :colorpalette)
|
||||||
|
|
|
@ -2,24 +2,25 @@
|
||||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
;;
|
;;
|
||||||
;; Copyright (c) 2015-2017 Andrey Antukh <niwi@niwi.nz>
|
|
||||||
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||||
|
;; Copyright (c) 2015-2019 Andrey Antukh <niwi@niwi.nz>
|
||||||
|
|
||||||
(ns uxbox.main.ui.workspace.images
|
(ns uxbox.main.ui.workspace.images
|
||||||
(:require [lentes.core :as l]
|
(:require
|
||||||
[rumext.core :as mx :include-macros true]
|
[lentes.core :as l]
|
||||||
[potok.core :as ptk]
|
[potok.core :as ptk]
|
||||||
[uxbox.builtins.icons :as i]
|
[rumext.core :as mx :include-macros true]
|
||||||
[uxbox.main.store :as st]
|
[uxbox.builtins.icons :as i]
|
||||||
[uxbox.main.data.lightbox :as udl]
|
[uxbox.main.data.images :as udi]
|
||||||
[uxbox.main.data.images :as udi]
|
[uxbox.main.data.lightbox :as udl]
|
||||||
[uxbox.main.data.workspace :as udw]
|
[uxbox.main.data.shapes :as uds]
|
||||||
[uxbox.main.data.shapes :as uds]
|
[uxbox.main.data.workspace :as udw]
|
||||||
[uxbox.main.ui.lightbox :as lbx]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.util.i18n :as t :refer [tr]]
|
[uxbox.main.ui.lightbox :as lbx]
|
||||||
[uxbox.util.data :refer [read-string jscoll->vec]]
|
[uxbox.util.data :refer [read-string jscoll->vec]]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
[uxbox.util.uuid :as uuid]))
|
[uxbox.util.i18n :as t :refer [tr]]
|
||||||
|
[uxbox.util.uuid :as uuid]))
|
||||||
|
|
||||||
;; --- Refs
|
;; --- Refs
|
||||||
|
|
||||||
|
@ -113,9 +114,9 @@
|
||||||
(-> (image-item image)
|
(-> (image-item image)
|
||||||
(mx/with-key (str (:id image)))))])
|
(mx/with-key (str (:id image)))))])
|
||||||
|
|
||||||
(defn will-mount
|
(defn init
|
||||||
[own]
|
[own]
|
||||||
(let [local (:rum/local own)]
|
(let [local (::mx/local own)]
|
||||||
(st/emit! (udi/fetch-collections))
|
(st/emit! (udi/fetch-collections))
|
||||||
(st/emit! (udi/fetch-images nil))
|
(st/emit! (udi/fetch-images nil))
|
||||||
(add-watch local ::key (fn [_ _ _ v]
|
(add-watch local ::key (fn [_ _ _ v]
|
||||||
|
@ -124,16 +125,16 @@
|
||||||
|
|
||||||
(defn will-unmount
|
(defn will-unmount
|
||||||
[own]
|
[own]
|
||||||
(let [local (:rum/local own)]
|
(let [local (::mx/local own)]
|
||||||
(remove-watch local ::key)
|
(remove-watch local ::key)
|
||||||
own))
|
own))
|
||||||
|
|
||||||
(mx/defcs image-collections-lightbox
|
(mx/defcs image-collections-lightbox
|
||||||
{:mixins [mx/reactive (mx/local)]
|
{:mixins [mx/reactive (mx/local)]
|
||||||
:will-mount will-mount
|
:init init
|
||||||
:will-unmount will-unmount}
|
:will-unmount will-unmount}
|
||||||
[own]
|
[own]
|
||||||
(let [local (:rum/local own)
|
(let [local (::mx/local own)
|
||||||
id (:id @local)
|
id (:id @local)
|
||||||
type (:type @local :own)
|
type (:type @local :own)
|
||||||
own? (= type :own)
|
own? (= type :own)
|
||||||
|
|
|
@ -6,13 +6,14 @@
|
||||||
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||||
|
|
||||||
(ns uxbox.main.ui.workspace.rules
|
(ns uxbox.main.ui.workspace.rules
|
||||||
(:require [cuerdas.core :as str]
|
(:require
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[uxbox.main.store :as s]
|
[cuerdas.core :as str]
|
||||||
[uxbox.main.constants :as c]
|
[rumext.core :as mx]
|
||||||
[uxbox.main.refs :as refs]
|
[uxbox.main.constants :as c]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.main.refs :as refs]
|
||||||
[rumext.core :as mx :include-macros true]))
|
[uxbox.main.store :as s]
|
||||||
|
[uxbox.util.dom :as dom]))
|
||||||
|
|
||||||
;; --- Constants & Helpers
|
;; --- Constants & Helpers
|
||||||
|
|
||||||
|
@ -65,102 +66,103 @@
|
||||||
|
|
||||||
;; --- Horizontal Text Label
|
;; --- Horizontal Text Label
|
||||||
|
|
||||||
(mx/defc horizontal-text-label
|
(mx/def horizontal-text-label
|
||||||
[zoom value]
|
:key-fn second
|
||||||
(let [big-ticks-mod (big-ticks-mod zoom)
|
:render
|
||||||
pos (+ (* value zoom)
|
(fn [own [zoom value]]
|
||||||
rule-padding
|
(let [big-ticks-mod (big-ticks-mod zoom)
|
||||||
(* c/canvas-start-x zoom)
|
pos (+ (* value zoom)
|
||||||
c/canvas-scroll-padding)]
|
rule-padding
|
||||||
(when (< (mod value big-ticks-mod) step-size)
|
(* c/canvas-start-x zoom)
|
||||||
[:text {:x (+ pos 2)
|
c/canvas-scroll-padding)]
|
||||||
:y 13
|
(when (< (mod value big-ticks-mod) step-size)
|
||||||
:key (str pos)
|
[:text {:x (+ pos 2)
|
||||||
:fill "#9da2a6"
|
:y 13
|
||||||
:style {:font-size "12px"}}
|
:key (str pos)
|
||||||
value])))
|
:fill "#9da2a6"
|
||||||
|
:style {:font-size "12px"}}
|
||||||
|
value]))))
|
||||||
|
|
||||||
;; --- Horizontal Text Label
|
;; --- Horizontal Text Label
|
||||||
|
|
||||||
(mx/defc vertical-text-label
|
(mx/def vertical-text-label
|
||||||
[zoom value]
|
:key-fn second
|
||||||
(let [big-ticks-mod (big-ticks-mod zoom)
|
:render
|
||||||
pos (+ (* value zoom)
|
(fn [own [zoom value]]
|
||||||
(* c/canvas-start-x zoom)
|
(let [big-ticks-mod (big-ticks-mod zoom)
|
||||||
;; c/canvas-start-x
|
pos (+ (* value zoom)
|
||||||
c/canvas-scroll-padding)]
|
(* c/canvas-start-x zoom)
|
||||||
(when (< (mod value big-ticks-mod) step-size)
|
c/canvas-scroll-padding)]
|
||||||
[:text {:y (- pos 3)
|
(when (< (mod value big-ticks-mod) step-size)
|
||||||
:x 5
|
[:text {:y (- pos 3)
|
||||||
:key (str pos)
|
:x 5
|
||||||
:fill "#9da2a6"
|
:key (str pos)
|
||||||
:transform (str/format "rotate(90 0 %s)" pos)
|
:fill "#9da2a6"
|
||||||
:style {:font-size "12px"}}
|
:transform (str/format "rotate(90 0 %s)" pos)
|
||||||
value])))
|
:style {:font-size "12px"}}
|
||||||
|
value]))))
|
||||||
|
|
||||||
;; --- Horizontal Rule Ticks (Component)
|
;; --- Horizontal Rule Ticks (Component)
|
||||||
|
|
||||||
(mx/defc horizontal-rule-ticks
|
(mx/def horizontal-rule-ticks
|
||||||
{:mixins [mx/static]}
|
:mixins #{mx/static}
|
||||||
[zoom]
|
:render
|
||||||
(let [zoom (or zoom 1)
|
(fn [own zoom]
|
||||||
path (reduce (partial make-vertical-tick zoom) [] +ticks+)
|
(let [zoom (or zoom 1)
|
||||||
labels (->> (map (partial horizontal-text-label zoom) +ticks+)
|
path (reduce (partial make-vertical-tick zoom) [] +ticks+)]
|
||||||
(filterv identity))]
|
[:g
|
||||||
[:g {}
|
[:path {:d (str/join " " path)}]
|
||||||
[:path {:d (str/join " " path)}]
|
(for [tick +ticks+]
|
||||||
(for [tick +ticks+]
|
(horizontal-text-label [zoom tick]))])))
|
||||||
(-> (horizontal-text-label zoom tick)
|
|
||||||
(mx/with-key (str tick))))]))
|
|
||||||
|
|
||||||
;; --- Vertical Rule Ticks (Component)
|
;; --- Vertical Rule Ticks (Component)
|
||||||
|
|
||||||
(mx/defc vertical-rule-ticks
|
(mx/def vertical-rule-ticks
|
||||||
{:mixins [mx/static]}
|
:mixins #{mx/static}
|
||||||
[zoom]
|
:render
|
||||||
(let [zoom (or zoom 1)
|
(fn [own zoom]
|
||||||
path (reduce (partial make-horizontal-tick zoom) [] +ticks+)
|
(let [zoom (or zoom 1)
|
||||||
labels (->> (map (partial vertical-text-label zoom) +ticks+)
|
path (reduce (partial make-horizontal-tick zoom) [] +ticks+)]
|
||||||
(filterv identity))]
|
[:g
|
||||||
[:g {}
|
[:path {:d (str/join " " path)}]
|
||||||
[:path {:d (str/join " " path)}]
|
(for [tick +ticks+]
|
||||||
(for [tick +ticks+]
|
(vertical-text-label [zoom tick]))])))
|
||||||
(-> (vertical-text-label zoom tick)
|
|
||||||
(mx/with-key (str tick))))]))
|
|
||||||
|
|
||||||
;; --- Horizontal Rule (Component)
|
;; --- Horizontal Rule (Component)
|
||||||
|
|
||||||
(mx/defc horizontal-rule
|
(mx/def horizontal-rule
|
||||||
{:mixins [mx/static mx/reactive]}
|
:mixins #{mx/static mx/reactive}
|
||||||
[]
|
:render
|
||||||
(let [scroll (mx/react refs/workspace-scroll)
|
(fn [own props]
|
||||||
zoom (mx/react refs/selected-zoom)
|
(let [scroll (mx/react refs/workspace-scroll)
|
||||||
scroll-x (:x scroll)
|
zoom (mx/react refs/selected-zoom)
|
||||||
translate-x (- (- c/canvas-scroll-padding) (:x scroll))]
|
scroll-x (:x scroll)
|
||||||
[:svg.horizontal-rule
|
translate-x (- (- c/canvas-scroll-padding) (:x scroll))]
|
||||||
{:width c/viewport-width
|
[:svg.horizontal-rule
|
||||||
:height 20}
|
{:width c/viewport-width
|
||||||
[:rect {:height 20
|
:height 20}
|
||||||
:width c/viewport-width}]
|
[:rect {:height 20
|
||||||
[:g {:transform (str "translate(" translate-x ", 0)")}
|
:width c/viewport-width}]
|
||||||
(horizontal-rule-ticks zoom)]]))
|
[:g {:transform (str "translate(" translate-x ", 0)")}
|
||||||
|
(horizontal-rule-ticks zoom)]])))
|
||||||
|
|
||||||
;; --- Vertical Rule (Component)
|
;; --- Vertical Rule (Component)
|
||||||
|
|
||||||
(mx/defc vertical-rule
|
(mx/def vertical-rule
|
||||||
{:mixins [mx/static mx/reactive]}
|
:mixins #{mx/static mx/reactive}
|
||||||
[]
|
:render
|
||||||
(let [scroll (mx/react refs/workspace-scroll)
|
(fn [own props]
|
||||||
zoom (mx/react refs/selected-zoom)
|
(let [scroll (mx/react refs/workspace-scroll)
|
||||||
scroll-y (:y scroll)
|
zoom (mx/react refs/selected-zoom)
|
||||||
translate-y (- (- c/canvas-scroll-padding) (:y scroll))]
|
scroll-y (:y scroll)
|
||||||
[:svg.vertical-rule
|
translate-y (- (- c/canvas-scroll-padding) (:y scroll))]
|
||||||
{:width 20
|
[:svg.vertical-rule
|
||||||
:height c/viewport-height}
|
{:width 20
|
||||||
|
:height c/viewport-height}
|
||||||
|
|
||||||
[:g {:transform (str "translate(0, " translate-y ")")}
|
[:g {:transform (str "translate(0, " translate-y ")")}
|
||||||
(vertical-rule-ticks zoom)]
|
(vertical-rule-ticks zoom)]
|
||||||
[:rect {:x 0
|
[:rect {:x 0
|
||||||
:y 0
|
:y 0
|
||||||
:height 20
|
:height 20
|
||||||
:width 20}]]))
|
:width 20}]])))
|
||||||
|
|
|
@ -98,7 +98,7 @@
|
||||||
|
|
||||||
;; --- Mixin
|
;; --- Mixin
|
||||||
|
|
||||||
(defn- will-mount
|
(defn- init
|
||||||
[own]
|
[own]
|
||||||
(assoc own ::sub (initialize)))
|
(assoc own ::sub (initialize)))
|
||||||
|
|
||||||
|
@ -108,5 +108,5 @@
|
||||||
(dissoc own ::sub))
|
(dissoc own ::sub))
|
||||||
|
|
||||||
(def shortcuts-mixin
|
(def shortcuts-mixin
|
||||||
{:will-mount will-mount
|
{:init init
|
||||||
:will-unmount will-unmount})
|
:will-unmount will-unmount})
|
||||||
|
|
|
@ -18,10 +18,9 @@
|
||||||
;; --- Left Sidebar (Component)
|
;; --- Left Sidebar (Component)
|
||||||
|
|
||||||
(mx/defc left-sidebar
|
(mx/defc left-sidebar
|
||||||
{:mixins [mx/static]}
|
[{:keys [flags page-id] :as props}]
|
||||||
[flags page-id]
|
[:aside#settings-bar.settings-bar.settings-bar-left
|
||||||
[:aside#settings-bar.settings-bar.settings-bar-left {}
|
[:div.settings-bar-inside
|
||||||
[:div.settings-bar-inside {}
|
|
||||||
(when (contains? flags :sitemap)
|
(when (contains? flags :sitemap)
|
||||||
(sitemap-toolbox page-id))
|
(sitemap-toolbox page-id))
|
||||||
(when (contains? flags :document-history)
|
(when (contains? flags :document-history)
|
||||||
|
@ -32,10 +31,9 @@
|
||||||
;; --- Right Sidebar (Component)
|
;; --- Right Sidebar (Component)
|
||||||
|
|
||||||
(mx/defc right-sidebar
|
(mx/defc right-sidebar
|
||||||
{:mixins [mx/static]}
|
[{:keys [flags page-id] :as props}]
|
||||||
[flags page-id]
|
[:aside#settings-bar.settings-bar
|
||||||
[:aside#settings-bar.settings-bar {}
|
[:div.settings-bar-inside
|
||||||
[:div.settings-bar-inside {}
|
|
||||||
(when (contains? flags :drawtools)
|
(when (contains? flags :drawtools)
|
||||||
(draw-toolbox flags))
|
(draw-toolbox flags))
|
||||||
(when (contains? flags :element-options)
|
(when (contains? flags :element-options)
|
||||||
|
|
|
@ -21,125 +21,115 @@
|
||||||
|
|
||||||
;; --- History Item (Component)
|
;; --- History Item (Component)
|
||||||
|
|
||||||
(mx/defc history-item
|
(mx/def history-item
|
||||||
{:mixins [mx/static]}
|
:mixins [mx/static]
|
||||||
[item selected]
|
:key-fn :id
|
||||||
(letfn [(on-select [event]
|
:render
|
||||||
(dom/prevent-default event)
|
(fn [own {:keys [::selected] :as item}]
|
||||||
(st/emit! (udh/select-page-history (:version item))))
|
(letfn [(on-select [event]
|
||||||
(on-pinned [event]
|
(dom/prevent-default event)
|
||||||
(dom/prevent-default event)
|
(st/emit! (udh/select-page-history (:version item))))
|
||||||
(dom/stop-propagation event)
|
(on-pinned [event]
|
||||||
(let [item (assoc item
|
(dom/prevent-default event)
|
||||||
:label "no label"
|
(dom/stop-propagation event)
|
||||||
:pinned (not (:pinned item)))]
|
(let [item (assoc item
|
||||||
(st/emit! (udh/update-history-item item))))]
|
:label "no label"
|
||||||
[:li {:class (when (= selected (:version item)) "current")
|
:pinned (not (:pinned item)))]
|
||||||
:on-click on-select}
|
(st/emit! (udh/update-history-item item))))]
|
||||||
[:div.pin-icon {:on-click on-pinned
|
[:li {:class (when (= selected (:version item)) "current")
|
||||||
:class (when (:pinned item) "selected")}
|
:on-click on-select}
|
||||||
i/pin]
|
[:div.pin-icon {:on-click on-pinned
|
||||||
[:span {} (str "Version " (:version item)
|
:class (when (:pinned item) "selected")}
|
||||||
" (" (dt/timeago (:created-at item)) ")")]]))
|
i/pin]
|
||||||
|
[:span (str "Version " (:version item)
|
||||||
|
" (" (dt/timeago (:created-at item)) ")")]])))
|
||||||
|
|
||||||
;; --- History List (Component)
|
;; --- History List (Component)
|
||||||
|
|
||||||
(mx/defc history-list
|
(mx/def history-list
|
||||||
{:mixins [mx/static mx/reactive]}
|
:mixins [mx/static mx/reactive]
|
||||||
[{:keys [selected items min-version] :as history}]
|
:render
|
||||||
(let [items (reverse (sort-by :version items))
|
(fn [own {:keys [selected items min-version] :as history}]
|
||||||
page (mx/react refs/selected-page)
|
(let [items (reverse (sort-by :version items))
|
||||||
show-more? (pos? min-version)
|
page (mx/react refs/selected-page)
|
||||||
load-more #(st/emit! (udh/load-more))]
|
show-more? (pos? min-version)
|
||||||
[:ul.history-content {}
|
load-more #(st/emit! (udh/load-more))]
|
||||||
(for [item items]
|
[:ul.history-content
|
||||||
(let [current? (= (:version item) (:version page))]
|
(for [item items]
|
||||||
(-> (history-item item selected current?)
|
(history-item (assoc item ::selectd selected)))
|
||||||
(mx/with-key (str (:id item))))))
|
(when show-more?
|
||||||
(when show-more?
|
[:li {:on-click load-more}
|
||||||
[:li {:on-click load-more}
|
[:a.btn-primary.btn-small
|
||||||
[:a.btn-primary.btn-small {}
|
"view more"]])])))
|
||||||
"view more"]])]))
|
|
||||||
|
|
||||||
;; --- History Pinned List (Component)
|
;; --- History Pinned List (Component)
|
||||||
|
|
||||||
(mx/defc history-pinned-list
|
(mx/def history-pinned-list
|
||||||
{:mixins [mx/static]}
|
:mixins [mx/static]
|
||||||
[{:keys [pinned selected] :as history}]
|
:render
|
||||||
[:ul.history-content {}
|
(fn [own {:keys [pinned selected] :as history}]
|
||||||
(for [item (reverse (sort-by :version pinned))]
|
[:ul.history-content
|
||||||
(let [selected? (= (:version item) selected)]
|
(for [item (reverse (sort-by :version pinned))]
|
||||||
(-> (history-item item selected?)
|
(let [selected (= (:version item) selected)]
|
||||||
(mx/with-key (str (:id item))))))])
|
(history-item (assoc item ::selected selected))))]))
|
||||||
|
|
||||||
;; --- History Toolbox (Component)
|
;; --- History Toolbox (Component)
|
||||||
|
|
||||||
|
(mx/def history-toolbox
|
||||||
|
:mixins [mx/static mx/reactive]
|
||||||
|
|
||||||
(defn- history-toolbox-will-mount
|
:init
|
||||||
[own]
|
(fn [own page-id]
|
||||||
(let [[page-id] (:rum/args own)]
|
|
||||||
(st/emit! (udh/initialize page-id))
|
(st/emit! (udh/initialize page-id))
|
||||||
own))
|
own)
|
||||||
|
|
||||||
(defn- history-toolbox-did-remount
|
:will-unmount
|
||||||
[oldown own]
|
(fn [own]
|
||||||
(let [[old-page-id] (:rum/args oldown)
|
(st/emit! ::udh/stop-changes-watcher)
|
||||||
[new-page-id] (:rum/args own)]
|
own)
|
||||||
(when-not (= old-page-id new-page-id)
|
|
||||||
(st/emit! ::udh/stop-changes-watcher
|
|
||||||
(udh/initialize new-page-id)))
|
|
||||||
own))
|
|
||||||
|
|
||||||
(defn- history-toolbox-will-unmount
|
:render
|
||||||
[own]
|
(fn [own page-id]
|
||||||
(st/emit! ::udh/stop-changes-watcher)
|
(let [history (mx/react refs/history)
|
||||||
own)
|
section (:section history :main)
|
||||||
|
|
||||||
(mx/defc history-toolbox
|
close #(st/emit! (dw/toggle-flag :document-history))
|
||||||
{:mixins [mx/static mx/reactive]
|
main? (= section :main)
|
||||||
:will-mount history-toolbox-will-mount
|
pinned? (= section :pinned)
|
||||||
:will-unmount history-toolbox-will-unmount
|
|
||||||
:did-remount history-toolbox-did-remount}
|
|
||||||
[_]
|
|
||||||
(let [history (mx/react refs/history)
|
|
||||||
section (:section history :main)
|
|
||||||
|
|
||||||
close #(st/emit! (dw/toggle-flag :document-history))
|
show-main #(st/emit! (udh/select-section :main))
|
||||||
main? (= section :main)
|
show-pinned #(st/emit! (udh/select-section :pinned))]
|
||||||
pinned? (= section :pinned)
|
[:div.document-history.tool-window {}
|
||||||
|
[:div.tool-window-bar {}
|
||||||
show-main #(st/emit! (udh/select-section :main))
|
[:div.tool-window-icon {} i/undo-history]
|
||||||
show-pinned #(st/emit! (udh/select-section :pinned))]
|
[:span {} (tr "ds.document-history")]
|
||||||
[:div.document-history.tool-window {}
|
[:div.tool-window-close {:on-click close} i/close]]
|
||||||
[:div.tool-window-bar {}
|
[:div.tool-window-content {}
|
||||||
[:div.tool-window-icon {} i/undo-history]
|
[:ul.history-tabs {}
|
||||||
[:span {} (tr "ds.document-history")]
|
[:li {:on-click show-main
|
||||||
[:div.tool-window-close {:on-click close} i/close]]
|
:class (when main? "selected")}
|
||||||
[:div.tool-window-content {}
|
"History"]
|
||||||
[:ul.history-tabs {}
|
[:li {:on-click show-pinned
|
||||||
[:li {:on-click show-main
|
:class (when pinned? "selected")}
|
||||||
:class (when main? "selected")}
|
"Pinned"]]
|
||||||
"History"]
|
(if (= section :pinned)
|
||||||
[:li {:on-click show-pinned
|
(history-pinned-list history)
|
||||||
:class (when pinned? "selected")}
|
(history-list history))]])))
|
||||||
"Pinned"]]
|
|
||||||
(if (= section :pinned)
|
|
||||||
(history-pinned-list history)
|
|
||||||
(history-list history))]]))
|
|
||||||
|
|
||||||
;; --- History Dialog
|
;; --- History Dialog
|
||||||
|
|
||||||
(mx/defc history-dialog
|
(mx/def history-dialog
|
||||||
{:mixins [mx/static mx/reactive]}
|
:mixins [mx/static mx/reactive]
|
||||||
[]
|
:render
|
||||||
(let [history (mx/react refs/history)
|
(fn [own]
|
||||||
version (:selected history)
|
(let [history (mx/react refs/history)
|
||||||
on-accept #(st/emit! (udh/apply-selected-history))
|
version (:selected history)
|
||||||
on-cancel #(st/emit! (udh/deselect-page-history))]
|
on-accept #(st/emit! (udh/apply-selected-history))
|
||||||
(when (or version (:deselecting history))
|
on-cancel #(st/emit! (udh/deselect-page-history))]
|
||||||
[:div.message-version
|
(when (or version (:deselecting history))
|
||||||
{:class (when (:deselecting history) "hide-message")}
|
[:div.message-version
|
||||||
[:span {} (tr "history.alert-message" (or version "00"))
|
{:class (when (:deselecting history) "hide-message")}
|
||||||
[:div.message-action {}
|
[:span {} (tr "history.alert-message" (or version "00"))
|
||||||
[:a.btn-transparent {:on-click on-accept} "Accept"]
|
[:div.message-action {}
|
||||||
[:a.btn-transparent {:on-click on-cancel} "Cancel"]]]])))
|
[:a.btn-transparent {:on-click on-accept} "Accept"]
|
||||||
|
[:a.btn-transparent {:on-click on-cancel} "Cancel"]]]]))))
|
||||||
|
|
|
@ -40,14 +40,14 @@
|
||||||
[icon]
|
[icon]
|
||||||
(icon/icon-svg icon))
|
(icon/icon-svg icon))
|
||||||
|
|
||||||
(defn- icons-toolbox-will-mount
|
(defn- icons-toolbox-init
|
||||||
[own]
|
[own]
|
||||||
(st/emit! (udw/initialize-icons-toolbox))
|
(st/emit! (udw/initialize-icons-toolbox))
|
||||||
own)
|
own)
|
||||||
|
|
||||||
(mx/defc icons-toolbox
|
(mx/defc icons-toolbox
|
||||||
{:mixins [mx/static mx/reactive]
|
{:mixins [mx/static mx/reactive]
|
||||||
:will-mount icons-toolbox-will-mount}
|
:init icons-toolbox-init}
|
||||||
[]
|
[]
|
||||||
(let [drawing (mx/react drawing-shape-ref)
|
(let [drawing (mx/react drawing-shape-ref)
|
||||||
selected (mx/react icons-toolbox-ref)
|
selected (mx/react icons-toolbox-ref)
|
||||||
|
|
|
@ -89,43 +89,42 @@
|
||||||
|
|
||||||
;; --- Shape Name (Component)
|
;; --- Shape Name (Component)
|
||||||
|
|
||||||
(mx/defcs shape-name
|
(mx/def shape-name
|
||||||
"A generic component that displays the shape name
|
:mixins [mx/static (mx/local)]
|
||||||
if it is available and allows inline edition of it."
|
:render
|
||||||
{:mixins [mx/static (mx/local)]}
|
(fn [{:keys [::mx/local] :as own} {:keys [id] :as shape}]
|
||||||
[{:keys [rum/local]} {:keys [id] :as shape}]
|
(letfn [(on-blur [event]
|
||||||
(letfn [(on-blur [event]
|
(let [target (dom/event->target event)
|
||||||
(let [target (dom/event->target event)
|
parent (.-parentNode target)
|
||||||
parent (.-parentNode target)
|
name (dom/get-value target)]
|
||||||
name (dom/get-value target)]
|
(set! (.-draggable parent) true)
|
||||||
(set! (.-draggable parent) true)
|
(st/emit! (uds/rename-shape id name))
|
||||||
(st/emit! (uds/rename-shape id name))
|
(swap! local assoc :edition false)))
|
||||||
(swap! local assoc :edition false)))
|
(on-key-down [event]
|
||||||
(on-key-down [event]
|
(js/console.log event)
|
||||||
(js/console.log event)
|
(when (kbd/enter? event)
|
||||||
(when (kbd/enter? event)
|
(on-blur event)))
|
||||||
(on-blur event)))
|
(on-click [event]
|
||||||
(on-click [event]
|
(dom/prevent-default event)
|
||||||
(dom/prevent-default event)
|
(let [parent (.-parentNode (.-target event))]
|
||||||
(let [parent (.-parentNode (.-target event))]
|
(set! (.-draggable parent) false))
|
||||||
(set! (.-draggable parent) false))
|
(swap! local assoc :edition true))]
|
||||||
(swap! local assoc :edition true))]
|
(if (:edition @local)
|
||||||
(if (:edition @local)
|
[:input.element-name
|
||||||
[:input.element-name
|
{:type "text"
|
||||||
{:type "text"
|
:on-blur on-blur
|
||||||
:on-blur on-blur
|
:on-key-down on-key-down
|
||||||
:on-key-down on-key-down
|
:auto-focus true
|
||||||
:auto-focus true
|
:default-value (:name shape "")}]
|
||||||
:default-value (:name shape "")}]
|
[:span.element-name
|
||||||
[:span.element-name
|
{:on-double-click on-click}
|
||||||
{:on-double-click on-click}
|
(:name shape "")]))))
|
||||||
(:name shape "")])))
|
|
||||||
|
|
||||||
;; --- Layer Simple (Component)
|
;; --- Layer Simple (Component)
|
||||||
|
|
||||||
(mx/defcs layer-simple
|
(mx/defcs layer-simple
|
||||||
{:mixins [mx/static (mx/local)]}
|
{:mixins [mx/static (mx/local)]}
|
||||||
[{:keys [rum/local]} item selected]
|
[{:keys [::mx/local]} item selected]
|
||||||
(let [selected? (contains? selected (:id item))
|
(let [selected? (contains? selected (:id item))
|
||||||
select #(select-shape selected item %)
|
select #(select-shape selected item %)
|
||||||
toggle-visibility #(toggle-visibility selected item %)
|
toggle-visibility #(toggle-visibility selected item %)
|
||||||
|
@ -189,14 +188,14 @@
|
||||||
{:class (when (:blocked item) "selected")
|
{:class (when (:blocked item) "selected")
|
||||||
:on-click toggle-blocking}
|
:on-click toggle-blocking}
|
||||||
i/lock]]
|
i/lock]]
|
||||||
[:div.element-icon {} (element-icon item)]
|
[:div.element-icon (element-icon item)]
|
||||||
(shape-name item)]])))
|
(shape-name item)]])))
|
||||||
|
|
||||||
;; --- Layer Group (Component)
|
;; --- Layer Group (Component)
|
||||||
|
|
||||||
(mx/defcs layer-group
|
(mx/defcs layer-group
|
||||||
{:mixins [mx/static mx/reactive (mx/local)]}
|
{:mixins [mx/static mx/reactive (mx/local)]}
|
||||||
[{:keys [rum/local]} {:keys [id] :as item} selected]
|
[{:keys [::mx/local]} {:keys [id] :as item} selected]
|
||||||
(let [selected? (contains? selected (:id item))
|
(let [selected? (contains? selected (:id item))
|
||||||
collapsed? (:collapsed item true)
|
collapsed? (:collapsed item true)
|
||||||
shapes-map (mx/react refs/shapes-by-id)
|
shapes-map (mx/react refs/shapes-by-id)
|
||||||
|
|
|
@ -8,27 +8,27 @@
|
||||||
(ns uxbox.main.ui.workspace.sidebar.options
|
(ns uxbox.main.ui.workspace.sidebar.options
|
||||||
(:require
|
(:require
|
||||||
[lentes.core :as l]
|
[lentes.core :as l]
|
||||||
[uxbox.util.i18n :refer [tr]]
|
|
||||||
[uxbox.util.router :as r]
|
|
||||||
[potok.core :as ptk]
|
[potok.core :as ptk]
|
||||||
[uxbox.main.store :as st]
|
[rumext.core :as mx :include-macros true]
|
||||||
[uxbox.main.data.workspace :as udw]
|
|
||||||
[uxbox.main.data.shapes :as uds]
|
|
||||||
[uxbox.builtins.icons :as i]
|
[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]
|
||||||
[uxbox.main.ui.shapes.attrs :refer [shape-default-attrs]]
|
[uxbox.main.ui.shapes.attrs :refer [shape-default-attrs]]
|
||||||
|
[uxbox.main.ui.workspace.sidebar.options.circle-measures :as options-circlem]
|
||||||
|
[uxbox.main.ui.workspace.sidebar.options.fill :as options-fill]
|
||||||
[uxbox.main.ui.workspace.sidebar.options.icon-measures :as options-iconm]
|
[uxbox.main.ui.workspace.sidebar.options.icon-measures :as options-iconm]
|
||||||
[uxbox.main.ui.workspace.sidebar.options.image-measures :as options-imagem]
|
[uxbox.main.ui.workspace.sidebar.options.image-measures :as options-imagem]
|
||||||
[uxbox.main.ui.workspace.sidebar.options.circle-measures :as options-circlem]
|
|
||||||
[uxbox.main.ui.workspace.sidebar.options.rect-measures :as options-rectm]
|
|
||||||
[uxbox.main.ui.workspace.sidebar.options.fill :as options-fill]
|
|
||||||
[uxbox.main.ui.workspace.sidebar.options.text :as options-text]
|
|
||||||
[uxbox.main.ui.workspace.sidebar.options.stroke :as options-stroke]
|
|
||||||
[uxbox.main.ui.workspace.sidebar.options.page :as options-page]
|
|
||||||
[uxbox.main.ui.workspace.sidebar.options.interactions :as options-interactions]
|
[uxbox.main.ui.workspace.sidebar.options.interactions :as options-interactions]
|
||||||
[uxbox.main.geom :as geom]
|
[uxbox.main.ui.workspace.sidebar.options.page :as options-page]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.main.ui.workspace.sidebar.options.rect-measures :as options-rectm]
|
||||||
|
[uxbox.main.ui.workspace.sidebar.options.stroke :as options-stroke]
|
||||||
|
[uxbox.main.ui.workspace.sidebar.options.text :as options-text]
|
||||||
[uxbox.util.data :as data]
|
[uxbox.util.data :as data]
|
||||||
[rumext.core :as mx :include-macros true]))
|
[uxbox.util.dom :as dom]
|
||||||
|
[uxbox.util.i18n :refer [tr]]
|
||||||
|
[uxbox.util.router :as r]))
|
||||||
|
|
||||||
;; --- Constants
|
;; --- Constants
|
||||||
|
|
||||||
|
@ -89,18 +89,10 @@
|
||||||
|
|
||||||
;; --- Options
|
;; --- Options
|
||||||
|
|
||||||
(defn- options-did-remount
|
|
||||||
[old-own own]
|
|
||||||
(let [[prev-shape] (:rum/args old-own)
|
|
||||||
[curr-shape] (:rum/args own)]
|
|
||||||
(when-not (= (:id prev-shape) (:id curr-shape))
|
|
||||||
(reset! (:rum/local own) {}))
|
|
||||||
own))
|
|
||||||
|
|
||||||
(mx/defcs options
|
(mx/defcs options
|
||||||
{:mixins [mx/static (mx/local)]
|
{:mixins [mx/static (mx/local)]
|
||||||
:did-remount options-did-remount}
|
:key-fn #(pr-str (:id %1))}
|
||||||
[{:keys [rum/local] :as own} shape]
|
[{:keys [::mx/local] :as own} shape]
|
||||||
(let [menus (get +menus-map+ (:type shape ::page))
|
(let [menus (get +menus-map+ (:type shape ::page))
|
||||||
contained-in? (into #{} menus)
|
contained-in? (into #{} menus)
|
||||||
active (:menu @local (first menus))]
|
active (:menu @local (first menus))]
|
||||||
|
|
|
@ -2,24 +2,25 @@
|
||||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
;;
|
;;
|
||||||
;; Copyright (c) 2015-2016 Andrey Antukh <niwi@niwi.nz>
|
|
||||||
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||||
|
;; Copyright (c) 2015-2019 Andrey Antukh <niwi@niwi.nz>
|
||||||
|
|
||||||
(ns uxbox.main.ui.workspace.sidebar.options.interactions
|
(ns uxbox.main.ui.workspace.sidebar.options.interactions
|
||||||
(:require [lentes.core :as l]
|
(:require
|
||||||
[uxbox.builtins.icons :as i]
|
[lentes.core :as l]
|
||||||
[uxbox.util.i18n :refer [tr]]
|
[rumext.core :as mx :include-macros true]
|
||||||
[uxbox.util.router :as r]
|
[uxbox.builtins.icons :as i]
|
||||||
[uxbox.main.refs :as refs]
|
[uxbox.main.data.lightbox :as udl]
|
||||||
[uxbox.main.store :as st]
|
[uxbox.main.data.shapes :as uds]
|
||||||
[uxbox.main.data.shapes :as uds]
|
[uxbox.main.refs :as refs]
|
||||||
[uxbox.main.data.lightbox :as udl]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.main.ui.lightbox :as lbx]
|
[uxbox.main.ui.colorpicker :as cp]
|
||||||
[uxbox.main.ui.colorpicker :as cp]
|
[uxbox.main.ui.lightbox :as lbx]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.data :refer [read-string]]
|
||||||
[uxbox.util.data :refer [read-string]]
|
[uxbox.util.dom :as dom]
|
||||||
[uxbox.util.spec :refer [color?]]
|
[uxbox.util.i18n :refer [tr]]
|
||||||
[rumext.core :as mx :include-macros true]))
|
[uxbox.util.router :as r]
|
||||||
|
[uxbox.util.spec :refer [color?]]))
|
||||||
|
|
||||||
;; --- Helpers
|
;; --- Helpers
|
||||||
|
|
||||||
|
@ -473,7 +474,7 @@
|
||||||
(mx/defcs interactions-menu
|
(mx/defcs interactions-menu
|
||||||
{:mixins [mx/static (mx/local)]}
|
{:mixins [mx/static (mx/local)]}
|
||||||
[own menu shape]
|
[own menu shape]
|
||||||
(let [local (:rum/local own)
|
(let [local (::mx/local own)
|
||||||
form-ref (l/derive (l/key :form) local)
|
form-ref (l/derive (l/key :form) local)
|
||||||
interactions (:interactions shape)
|
interactions (:interactions shape)
|
||||||
create-interaction #(reset! form-ref {})]
|
create-interaction #(reset! form-ref {})]
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
(mx/defcs stroke-menu
|
(mx/defcs stroke-menu
|
||||||
{:mixins [mx/static (mx/local)]}
|
{:mixins [mx/static (mx/local)]}
|
||||||
[{:keys [rum/local]} menu {:keys [id] :as shape}]
|
[{:keys [::mx/local]} menu {:keys [id] :as shape}]
|
||||||
(letfn [(on-width-change [event]
|
(letfn [(on-width-change [event]
|
||||||
(let [value (-> (dom/event->value event)
|
(let [value (-> (dom/event->value event)
|
||||||
(parse-float 1))]
|
(parse-float 1))]
|
||||||
|
|
|
@ -6,119 +6,126 @@
|
||||||
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||||
|
|
||||||
(ns uxbox.main.ui.workspace.sidebar.sitemap
|
(ns uxbox.main.ui.workspace.sidebar.sitemap
|
||||||
(:require [lentes.core :as l]
|
(:require
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[uxbox.builtins.icons :as i]
|
[lentes.core :as l]
|
||||||
[uxbox.main.store :as st]
|
[rumext.core :as mx :include-macros true]
|
||||||
[uxbox.main.refs :as refs]
|
[uxbox.builtins.icons :as i]
|
||||||
[uxbox.main.data.projects :as dp]
|
[uxbox.main.data.lightbox :as udl]
|
||||||
[uxbox.main.data.pages :as udp]
|
[uxbox.main.data.pages :as udp]
|
||||||
[uxbox.main.data.workspace :as dw]
|
[uxbox.main.data.projects :as dp]
|
||||||
[uxbox.main.data.lightbox :as udl]
|
[uxbox.main.data.workspace :as dw]
|
||||||
[uxbox.main.ui.workspace.sidebar.sitemap-pageform]
|
[uxbox.main.refs :as refs]
|
||||||
[uxbox.main.ui.lightbox :as lbx]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.util.i18n :refer (tr)]
|
[uxbox.main.ui.lightbox :as lbx]
|
||||||
[uxbox.util.router :as r]
|
[uxbox.main.ui.workspace.sidebar.sitemap-pageform]
|
||||||
[uxbox.util.data :refer [classnames]]
|
[uxbox.util.data :refer [classnames]]
|
||||||
[uxbox.util.dom.dnd :as dnd]
|
[uxbox.util.dom :as dom]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom.dnd :as dnd]
|
||||||
[rumext.core :as mx :include-macros true]))
|
[uxbox.util.i18n :refer (tr)]
|
||||||
|
[uxbox.util.router :as r]))
|
||||||
|
|
||||||
(mx/defcs page-item
|
(mx/def page-item
|
||||||
{:mixins [(mx/local) mx/static mx/reactive]}
|
:mixins [(mx/local) mx/static mx/reactive]
|
||||||
[{:keys [rum/local] :as own} page total active?]
|
:key-fn :id
|
||||||
(let [body-classes (classnames
|
|
||||||
:selected active?
|
|
||||||
:drag-active (:dragging @local)
|
|
||||||
:drag-top (= :top (:over @local))
|
|
||||||
:drag-bottom (= :bottom (:over @local))
|
|
||||||
:drag-inside (= :middle (:over @local)))
|
|
||||||
li-classes (classnames
|
|
||||||
:selected active?
|
|
||||||
:hide (:dragging @local))]
|
|
||||||
(letfn [(on-edit [event]
|
|
||||||
(udl/open! :page-form {:page page}))
|
|
||||||
|
|
||||||
(on-navigate [event]
|
:render
|
||||||
(st/emit! (dp/go-to (:project page) (:id page))))
|
(fn [{:keys [::mx/local] :as own}
|
||||||
|
{:keys [::deletable? ::selected?] :as page}]
|
||||||
|
(let [body-classes (classnames
|
||||||
|
:selected selected?
|
||||||
|
:drag-active (:dragging @local)
|
||||||
|
:drag-top (= :top (:over @local))
|
||||||
|
:drag-bottom (= :bottom (:over @local))
|
||||||
|
:drag-inside (= :middle (:over @local)))
|
||||||
|
li-classes (classnames
|
||||||
|
:selected selected?
|
||||||
|
:hide (:dragging @local))]
|
||||||
|
(letfn [(on-edit [event]
|
||||||
|
(udl/open! :page-form {:page page}))
|
||||||
|
|
||||||
(delete []
|
(on-navigate [event]
|
||||||
(let [next #(st/emit! (dp/go-to (:project page)))]
|
(st/emit! (dp/go-to (:project page) (:id page))))
|
||||||
(st/emit! (udp/delete-page (:id page) next))))
|
|
||||||
|
|
||||||
(on-delete [event]
|
(delete []
|
||||||
(dom/prevent-default event)
|
(let [next #(st/emit! (dp/go-to (:project page)))]
|
||||||
(dom/stop-propagation event)
|
(st/emit! (udp/delete-page (:id page) next))))
|
||||||
(udl/open! :confirm {:on-accept delete}))
|
|
||||||
|
|
||||||
(on-drag-start [event]
|
(on-delete [event]
|
||||||
(let [target (dom/event->target event)]
|
(dom/prevent-default event)
|
||||||
(dnd/set-allowed-effect! event "move")
|
(dom/stop-propagation event)
|
||||||
(dnd/set-data! event (:id page))
|
(udl/open! :confirm {:on-accept delete}))
|
||||||
(dnd/set-image! event target 50 10)
|
|
||||||
(swap! local assoc :dragging true)))
|
|
||||||
(on-drag-end [event]
|
|
||||||
(swap! local assoc :dragging false :over nil))
|
|
||||||
(on-drop [event]
|
|
||||||
(dom/stop-propagation event)
|
|
||||||
(let [id (dnd/get-data event)
|
|
||||||
over (:over @local)]
|
|
||||||
(case (:over @local)
|
|
||||||
:top (let [new-order (dec (get-in page [:metadata :order]))]
|
|
||||||
(st/emit! (udp/update-order id new-order)))
|
|
||||||
:bottom (let [new-order (inc (get-in page [:metadata :order]))]
|
|
||||||
(st/emit! (udp/update-order id new-order))))
|
|
||||||
(swap! local assoc :dragging false :over nil)))
|
|
||||||
(on-drag-over [event]
|
|
||||||
(dom/prevent-default event)
|
|
||||||
(dnd/set-drop-effect! event "move")
|
|
||||||
(let [over (dnd/get-hover-position event false)]
|
|
||||||
(swap! local assoc :over over)))
|
|
||||||
(on-drag-enter [event]
|
|
||||||
(swap! local assoc :over true))
|
|
||||||
(on-drag-leave [event]
|
|
||||||
(swap! local assoc :over false))]
|
|
||||||
[:li {:class li-classes}
|
|
||||||
[:div.element-list-body
|
|
||||||
{:class body-classes
|
|
||||||
:style {:opacity (if (:dragging @local)
|
|
||||||
"0.5"
|
|
||||||
"1")}
|
|
||||||
:on-click on-navigate
|
|
||||||
:on-double-click #(dom/stop-propagation %)
|
|
||||||
:on-drag-start on-drag-start
|
|
||||||
:on-drag-enter on-drag-enter
|
|
||||||
:on-drag-leave on-drag-leave
|
|
||||||
:on-drag-over on-drag-over
|
|
||||||
:on-drag-end on-drag-end
|
|
||||||
:on-drop on-drop
|
|
||||||
:draggable true}
|
|
||||||
|
|
||||||
[:div.page-icon {} i/page]
|
(on-drag-start [event]
|
||||||
[:span {} (:name page)]
|
(let [target (dom/event->target event)]
|
||||||
[:div.page-actions {}
|
(dnd/set-allowed-effect! event "move")
|
||||||
[:a {:on-click on-edit} i/pencil]
|
(dnd/set-data! event (:id page))
|
||||||
(when (> total 1)
|
(dnd/set-image! event target 50 10)
|
||||||
[:a {:on-click on-delete} i/trash])]]])))
|
(swap! local assoc :dragging true)))
|
||||||
|
(on-drag-end [event]
|
||||||
|
(swap! local assoc :dragging false :over nil))
|
||||||
|
(on-drop [event]
|
||||||
|
(dom/stop-propagation event)
|
||||||
|
(let [id (dnd/get-data event)
|
||||||
|
over (:over @local)]
|
||||||
|
(case (:over @local)
|
||||||
|
:top (let [new-order (dec (get-in page [:metadata :order]))]
|
||||||
|
(st/emit! (udp/update-order id new-order)))
|
||||||
|
:bottom (let [new-order (inc (get-in page [:metadata :order]))]
|
||||||
|
(st/emit! (udp/update-order id new-order))))
|
||||||
|
(swap! local assoc :dragging false :over nil)))
|
||||||
|
(on-drag-over [event]
|
||||||
|
(dom/prevent-default event)
|
||||||
|
(dnd/set-drop-effect! event "move")
|
||||||
|
(let [over (dnd/get-hover-position event false)]
|
||||||
|
(swap! local assoc :over over)))
|
||||||
|
(on-drag-enter [event]
|
||||||
|
(swap! local assoc :over true))
|
||||||
|
(on-drag-leave [event]
|
||||||
|
(swap! local assoc :over false))]
|
||||||
|
[:li {:class li-classes}
|
||||||
|
[:div.element-list-body
|
||||||
|
{:class body-classes
|
||||||
|
:style {:opacity (if (:dragging @local)
|
||||||
|
"0.5"
|
||||||
|
"1")}
|
||||||
|
:on-click on-navigate
|
||||||
|
:on-double-click #(dom/stop-propagation %)
|
||||||
|
:on-drag-start on-drag-start
|
||||||
|
:on-drag-enter on-drag-enter
|
||||||
|
:on-drag-leave on-drag-leave
|
||||||
|
:on-drag-over on-drag-over
|
||||||
|
:on-drag-end on-drag-end
|
||||||
|
:on-drop on-drop
|
||||||
|
:draggable true}
|
||||||
|
|
||||||
(mx/defc sitemap-toolbox
|
[:div.page-icon {} i/page]
|
||||||
{:mixins [mx/static mx/reactive]}
|
[:span {} (:name page)]
|
||||||
[current]
|
[:div.page-actions {}
|
||||||
(let [project (mx/react refs/selected-project)
|
[:a {:on-click on-edit} i/pencil]
|
||||||
pages (mx/react refs/selected-project-pages)
|
(when deletable?
|
||||||
create #(udl/open! :page-form {:page {:project (:id project)}})
|
[:a {:on-click on-delete} i/trash])]]]))))
|
||||||
close #(st/emit! (dw/toggle-flag :sitemap))]
|
|
||||||
[:div.sitemap.tool-window {}
|
(mx/def sitemap-toolbox
|
||||||
[:div.tool-window-bar {}
|
:mixins [mx/static mx/reactive]
|
||||||
[:div.tool-window-icon {} i/project-tree]
|
|
||||||
[:span {} (tr "ds.sitemap")]
|
:render
|
||||||
[:div.tool-window-close {:on-click close} i/close]]
|
(fn [own current-page-id]
|
||||||
[:div.tool-window-content {}
|
(let [project (mx/react refs/selected-project)
|
||||||
[:div.project-title {}
|
pages (mx/react refs/selected-project-pages)
|
||||||
[:span {} (:name project)]
|
create #(udl/open! :page-form {:page {:project (:id project)}})
|
||||||
[:div.add-page {:on-click create} i/close]]
|
close #(st/emit! (dw/toggle-flag :sitemap))
|
||||||
[:ul.element-list {}
|
deletable? (> (count pages) 1)]
|
||||||
(for [page pages]
|
[:div.sitemap.tool-window
|
||||||
(let [active? (= (:id page) current)]
|
[:div.tool-window-bar
|
||||||
(-> (page-item page (count pages) active?)
|
[:div.tool-window-icon i/project-tree]
|
||||||
(mx/with-key (:id page)))))]]]))
|
[:span (tr "ds.sitemap")]
|
||||||
|
[:div.tool-window-close {:on-click close} i/close]]
|
||||||
|
[:div.tool-window-content
|
||||||
|
[:div.project-title
|
||||||
|
[:span (:name project)]
|
||||||
|
[:div.add-page {:on-click create} i/close]]
|
||||||
|
[:ul.element-list
|
||||||
|
(for [page pages]
|
||||||
|
(let [selected? (= (:id page) current-page-id)]
|
||||||
|
(page-item (assoc page ::deletable? deletable? ::selected? selected?))))]]])))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue