mirror of
https://github.com/penpot/penpot.git
synced 2025-06-03 14:31:38 +02:00
🎉 Add option to save the layouts
This commit is contained in:
parent
8d9e772dca
commit
1d2ae6d5eb
17 changed files with 310 additions and 271 deletions
|
@ -14,6 +14,38 @@
|
||||||
[uxbox.common.uuid :as uuid]
|
[uxbox.common.uuid :as uuid]
|
||||||
[uxbox.tests.helpers :as th]))
|
[uxbox.tests.helpers :as th]))
|
||||||
|
|
||||||
|
(t/deftest process-change-set-option
|
||||||
|
(let [data cp/default-page-data]
|
||||||
|
(t/testing "Sets option single"
|
||||||
|
(let [chg {:type :set-option
|
||||||
|
:option :test
|
||||||
|
:value "test"}
|
||||||
|
res (cp/process-changes data [chg])]
|
||||||
|
(t/is (= "test" (get-in res [:options :test])))))
|
||||||
|
|
||||||
|
(t/testing "Sets option nested"
|
||||||
|
(let [chgs [{:type :set-option
|
||||||
|
:option [:values :test :a]
|
||||||
|
:value "a"}
|
||||||
|
{:type :set-option
|
||||||
|
:option [:values :test :b]
|
||||||
|
:value "b"}]
|
||||||
|
res (cp/process-changes data chgs)]
|
||||||
|
(t/is (= {:a "a" :b "b"} (get-in res [:options :values :test])))))
|
||||||
|
|
||||||
|
(t/testing "Remove option"
|
||||||
|
(let [chgs [{:type :set-option
|
||||||
|
:option [:values :test :a]
|
||||||
|
:value "a"}
|
||||||
|
{:type :set-option
|
||||||
|
:option [:values :test :b]
|
||||||
|
:value "b"}
|
||||||
|
{:type :set-option
|
||||||
|
:option [:values :test]
|
||||||
|
:value nil}]
|
||||||
|
res (cp/process-changes data chgs)]
|
||||||
|
(t/is (= nil (get-in res [:options :values :test])))))))
|
||||||
|
|
||||||
(t/deftest process-change-add-obj
|
(t/deftest process-change-add-obj
|
||||||
(let [data cp/default-page-data
|
(let [data cp/default-page-data
|
||||||
id-a (uuid/next)
|
id-a (uuid/next)
|
||||||
|
|
|
@ -253,6 +253,12 @@
|
||||||
|
|
||||||
(defmulti change-spec-impl :type)
|
(defmulti change-spec-impl :type)
|
||||||
|
|
||||||
|
(s/def :set-option/option any? #_(s/or keyword? (s/coll-of keyword?)))
|
||||||
|
(s/def :set-option/value any?)
|
||||||
|
|
||||||
|
(defmethod change-spec-impl :set-option [_]
|
||||||
|
(s/keys :req-un [:set-option/option :set-option/value]))
|
||||||
|
|
||||||
(defmethod change-spec-impl :add-obj [_]
|
(defmethod change-spec-impl :add-obj [_]
|
||||||
(s/keys :req-un [::id ::frame-id ::obj]
|
(s/keys :req-un [::id ::frame-id ::obj]
|
||||||
:opt-un [::session-id ::parent-id]))
|
:opt-un [::session-id ::parent-id]))
|
||||||
|
@ -313,6 +319,12 @@
|
||||||
|
|
||||||
(declare insert-at-index)
|
(declare insert-at-index)
|
||||||
|
|
||||||
|
(defmethod process-change :set-option
|
||||||
|
[data {:keys [option value]}]
|
||||||
|
(let [path (if (seqable? option) option [option])]
|
||||||
|
(-> data
|
||||||
|
(assoc-in (into [:options] path) value))))
|
||||||
|
|
||||||
(defmethod process-change :add-obj
|
(defmethod process-change :add-obj
|
||||||
[data {:keys [id obj frame-id parent-id index] :as change}]
|
[data {:keys [id obj frame-id parent-id index] :as change}]
|
||||||
(let [parent-id (or parent-id frame-id)
|
(let [parent-id (or parent-id frame-id)
|
||||||
|
|
|
@ -1,28 +1,28 @@
|
||||||
{
|
{
|
||||||
"dashboard.grid.delete" : {
|
"dashboard.grid.delete" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/dashboard/project.cljs:61", "src/uxbox/main/ui/dashboard/grid.cljs:92" ],
|
"used-in" : [ "src/uxbox/main/ui/dashboard/grid.cljs:102", "src/uxbox/main/ui/dashboard/project.cljs:62" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Delete"
|
"en" : "Delete"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dashboard.grid.edit" : {
|
"dashboard.grid.edit" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/dashboard/project.cljs:60", "src/uxbox/main/ui/dashboard/grid.cljs:91" ],
|
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Edit"
|
"en" : "Edit"
|
||||||
|
},
|
||||||
|
"unused" : true
|
||||||
|
},
|
||||||
|
"dashboard.grid.empty-files" : {
|
||||||
|
"used-in" : [ "src/uxbox/main/ui/dashboard/grid.cljs:124" ],
|
||||||
|
"translations" : {
|
||||||
|
"en" : "You still have no files here"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dashboard.grid.rename" : {
|
"dashboard.grid.rename" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/dashboard/project.cljs:60", "src/uxbox/main/ui/dashboard/grid.cljs:91" ],
|
"used-in" : [ "src/uxbox/main/ui/dashboard/grid.cljs:101", "src/uxbox/main/ui/dashboard/project.cljs:61" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Rename"
|
"en" : "Rename"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dashboard.grid.empty-files" : {
|
|
||||||
"used-in" : [ "src/uxbox/main/ui/dashboard/grid.cljs:114" ],
|
|
||||||
"translations" : {
|
|
||||||
"en" : "You still have no files here"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dashboard.header.draft" : {
|
"dashboard.header.draft" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/dashboard/project.cljs:55" ],
|
"used-in" : [ "src/uxbox/main/ui/dashboard/project.cljs:55" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
|
@ -63,7 +63,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dashboard.header.project" : {
|
"dashboard.header.project" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/dashboard/project.cljs:68" ],
|
"used-in" : [ "src/uxbox/main/ui/dashboard/project.cljs:57" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Project %s"
|
"en" : "Project %s"
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ds.button.delete" : {
|
"ds.button.delete" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/dashboard/library.cljs:152", "src/uxbox/main/ui/dashboard/library.cljs:220", "src/uxbox/main/ui/dashboard/library.cljs:257", "src/uxbox/main/ui/dashboard/library.cljs:296" ],
|
"used-in" : [ "src/uxbox/main/ui/dashboard/library.cljs:152", "src/uxbox/main/ui/dashboard/library.cljs:220", "src/uxbox/main/ui/dashboard/library.cljs:259", "src/uxbox/main/ui/dashboard/library.cljs:300" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Delete"
|
"en" : "Delete"
|
||||||
}
|
}
|
||||||
|
@ -257,7 +257,7 @@
|
||||||
"unused" : true
|
"unused" : true
|
||||||
},
|
},
|
||||||
"ds.new-file" : {
|
"ds.new-file" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/dashboard/grid.cljs:110", "src/uxbox/main/ui/dashboard/grid.cljs:116" ],
|
"used-in" : [ "src/uxbox/main/ui/dashboard/grid.cljs:120", "src/uxbox/main/ui/dashboard/grid.cljs:126" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "+ New File",
|
"en" : "+ New File",
|
||||||
"fr" : null
|
"fr" : null
|
||||||
|
@ -299,7 +299,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ds.updated-at" : {
|
"ds.updated-at" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/dashboard/grid.cljs:35" ],
|
"used-in" : [ "src/uxbox/main/ui/dashboard/grid.cljs:45" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Updated: %s",
|
"en" : "Updated: %s",
|
||||||
"fr" : "Mis à jour: %s"
|
"fr" : "Mis à jour: %s"
|
||||||
|
@ -341,21 +341,21 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"errors.generic" : {
|
"errors.generic" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui.cljs:179" ],
|
"used-in" : [ "src/uxbox/main/ui.cljs:178" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Something wrong has happened.",
|
"en" : "Something wrong has happened.",
|
||||||
"fr" : "Quelque chose c'est mal passé."
|
"fr" : "Quelque chose c'est mal passé."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"errors.network" : {
|
"errors.network" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui.cljs:173" ],
|
"used-in" : [ "src/uxbox/main/ui.cljs:172" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Unable to connect to backend server.",
|
"en" : "Unable to connect to backend server.",
|
||||||
"fr" : "Impossible de se connecter au serveur principal."
|
"fr" : "Impossible de se connecter au serveur principal."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"header.sitemap" : {
|
"header.sitemap" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:74" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:68" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : null,
|
"en" : null,
|
||||||
"fr" : null
|
"fr" : null
|
||||||
|
@ -459,7 +459,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"profile.recovery.go-to-login" : {
|
"profile.recovery.go-to-login" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/profile/recovery_request.cljs:65", "src/uxbox/main/ui/profile/recovery.cljs:81" ],
|
"used-in" : [ "src/uxbox/main/ui/profile/recovery.cljs:81", "src/uxbox/main/ui/profile/recovery_request.cljs:65" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Go back!",
|
"en" : "Go back!",
|
||||||
"fr" : "Retour!"
|
"fr" : "Retour!"
|
||||||
|
@ -702,73 +702,73 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"viewer.header.dont-show-interactions" : {
|
"viewer.header.dont-show-interactions" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:40" ],
|
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:67" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Don't show interactions"
|
"en" : "Don't show interactions"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"viewer.header.edit-page" : {
|
"viewer.header.edit-page" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:137" ],
|
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:164" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Edit page"
|
"en" : "Edit page"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"viewer.header.fullscreen" : {
|
"viewer.header.fullscreen" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:148" ],
|
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:175" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Full Screen"
|
"en" : "Full Screen"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"viewer.header.share.copy-link" : {
|
"viewer.header.share.copy-link" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:86" ],
|
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:113" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Copy link"
|
"en" : "Copy link"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"viewer.header.share.create-link" : {
|
"viewer.header.share.create-link" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:94" ],
|
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:121" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Create link"
|
"en" : "Create link"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"viewer.header.share.placeholder" : {
|
"viewer.header.share.placeholder" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:84" ],
|
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:111" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Share link will apear here"
|
"en" : "Share link will apear here"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"viewer.header.share.remove-link" : {
|
"viewer.header.share.remove-link" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:92" ],
|
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:119" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Remove link"
|
"en" : "Remove link"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"viewer.header.share.subtitle" : {
|
"viewer.header.share.subtitle" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:88" ],
|
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:115" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Anyone with the link will have access"
|
"en" : "Anyone with the link will have access"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"viewer.header.share.title" : {
|
"viewer.header.share.title" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:72", "src/uxbox/main/ui/viewer/header.cljs:74", "src/uxbox/main/ui/viewer/header.cljs:80" ],
|
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:99", "src/uxbox/main/ui/viewer/header.cljs:101", "src/uxbox/main/ui/viewer/header.cljs:107" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Share link"
|
"en" : "Share link"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"viewer.header.show-interactions" : {
|
"viewer.header.show-interactions" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:44" ],
|
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:71" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Show interactions"
|
"en" : "Show interactions"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"viewer.header.show-interactions-on-click" : {
|
"viewer.header.show-interactions-on-click" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:48" ],
|
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:75" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Show interactions on click"
|
"en" : "Show interactions on click"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"viewer.header.sitemap" : {
|
"viewer.header.sitemap" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:121" ],
|
"used-in" : [ "src/uxbox/main/ui/viewer/header.cljs:148" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Sitemap"
|
"en" : "Sitemap"
|
||||||
}
|
}
|
||||||
|
@ -821,70 +821,92 @@
|
||||||
"en" : "Align top"
|
"en" : "Align top"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"workspace.header.menu.disable-dynamic-alignment" : {
|
||||||
|
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:116" ],
|
||||||
|
"translations" : {
|
||||||
|
"en" : "Disable dynamic alignment"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"workspace.header.menu.disable-snap-grid" : {
|
||||||
|
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:92" ],
|
||||||
|
"translations" : {
|
||||||
|
"en" : "Disable snap to grid"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"workspace.header.menu.enable-dynamic-alignment" : {
|
||||||
|
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:117" ],
|
||||||
|
"translations" : {
|
||||||
|
"en" : "Enable dynamic aligment"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"workspace.header.menu.enable-snap-grid" : {
|
||||||
|
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:93" ],
|
||||||
|
"translations" : {
|
||||||
|
"en" : "Snap to grid"
|
||||||
|
}
|
||||||
|
},
|
||||||
"workspace.header.menu.hide-grid" : {
|
"workspace.header.menu.hide-grid" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:94" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:86" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Hide grid"
|
"en" : "Hide grid"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.header.menu.hide-layers" : {
|
"workspace.header.menu.hide-layers" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:101" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:98" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Hide layers"
|
"en" : "Hide layers"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.header.menu.hide-libraries" : {
|
"workspace.header.menu.hide-libraries" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:115" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:110" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Hide libraries"
|
"en" : "Hide libraries"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.header.menu.hide-palette" : {
|
"workspace.header.menu.hide-palette" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:108" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:104" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Hide color palette"
|
"en" : "Hide color palette"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.header.menu.hide-rules" : {
|
"workspace.header.menu.hide-rules" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:87" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:80" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Hide rules"
|
"en" : "Hide rules"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.header.menu.show-grid" : {
|
"workspace.header.menu.show-grid" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:95" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:87" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Show grid"
|
"en" : "Show grid"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.header.menu.show-layers" : {
|
"workspace.header.menu.show-layers" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:102" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:99" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Show layers"
|
"en" : "Show layers"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.header.menu.show-libraries" : {
|
"workspace.header.menu.show-libraries" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:116" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:111" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Show libraries"
|
"en" : "Show libraries"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.header.menu.show-palette" : {
|
"workspace.header.menu.show-palette" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:109" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:105" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Show color palette"
|
"en" : "Show color palette"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.header.menu.show-rules" : {
|
"workspace.header.menu.show-rules" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:88" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:81" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Show rules"
|
"en" : "Show rules"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.header.menu.disable-dynamic-alignment": "Disable dynamic alignment",
|
|
||||||
"workspace.header.menu.enable-dynamic-alignment": "Enable dynamic aligment",
|
|
||||||
"workspace.header.viewer" : {
|
"workspace.header.viewer" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:153" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/header.cljs:154" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "View mode (Ctrl + P)",
|
"en" : "View mode (Ctrl + P)",
|
||||||
"fr" : "Mode visualisation (Ctrl + P)"
|
"fr" : "Mode visualisation (Ctrl + P)"
|
||||||
|
@ -927,11 +949,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.options.color" : {
|
"workspace.options.color" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:89" ],
|
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Color",
|
"en" : "Color",
|
||||||
"fr" : "Couleur"
|
"fr" : "Couleur"
|
||||||
}
|
},
|
||||||
|
"unused" : true
|
||||||
},
|
},
|
||||||
"workspace.options.design" : {
|
"workspace.options.design" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options.cljs:76" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options.cljs:76" ],
|
||||||
|
@ -940,7 +962,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.options.fill" : {
|
"workspace.options.fill" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/fill.cljs:69", "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:446" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:446", "src/uxbox/main/ui/workspace/sidebar/options/fill.cljs:71" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Fill",
|
"en" : "Fill",
|
||||||
"fr" : "Fond"
|
"fr" : "Fond"
|
||||||
|
@ -1076,11 +1098,11 @@
|
||||||
"unused" : true
|
"unused" : true
|
||||||
},
|
},
|
||||||
"workspace.options.grid-options" : {
|
"workspace.options.grid-options" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:76" ],
|
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Grid settings",
|
"en" : "Grid settings",
|
||||||
"fr" : "Paramètres de la grille"
|
"fr" : "Paramètres de la grille"
|
||||||
}
|
},
|
||||||
|
"unused" : true
|
||||||
},
|
},
|
||||||
"workspace.options.line-height-letter-spacing" : {
|
"workspace.options.line-height-letter-spacing" : {
|
||||||
"translations" : {
|
"translations" : {
|
||||||
|
@ -1097,13 +1119,13 @@
|
||||||
"unused" : true
|
"unused" : true
|
||||||
},
|
},
|
||||||
"workspace.options.navigate-to" : {
|
"workspace.options.navigate-to" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:51" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:58" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Navigate to"
|
"en" : "Navigate to"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.options.none" : {
|
"workspace.options.none" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:64" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:71" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "None"
|
"en" : "None"
|
||||||
}
|
}
|
||||||
|
@ -1116,7 +1138,7 @@
|
||||||
"unused" : true
|
"unused" : true
|
||||||
},
|
},
|
||||||
"workspace.options.position" : {
|
"workspace.options.position" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:135", "src/uxbox/main/ui/workspace/sidebar/options/frame.cljs:126" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/frame.cljs:127", "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:138" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Position",
|
"en" : "Position",
|
||||||
"fr" : "Position"
|
"fr" : "Position"
|
||||||
|
@ -1129,14 +1151,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.options.radius" : {
|
"workspace.options.radius" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:183" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:179" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Radius",
|
"en" : "Radius",
|
||||||
"fr" : "TODO"
|
"fr" : "TODO"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.options.rotation" : {
|
"workspace.options.rotation" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:159" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:154" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Rotation",
|
"en" : "Rotation",
|
||||||
"fr" : "TODO"
|
"fr" : "TODO"
|
||||||
|
@ -1150,78 +1172,78 @@
|
||||||
"unused" : true
|
"unused" : true
|
||||||
},
|
},
|
||||||
"workspace.options.select-a-shape" : {
|
"workspace.options.select-a-shape" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:45" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:52" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Select a shape, artboard or group to drag a connection to other artboard."
|
"en" : "Select a shape, artboard or group to drag a connection to other artboard."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.options.select-artboard" : {
|
"workspace.options.select-artboard" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:57" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:64" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Select artboard"
|
"en" : "Select artboard"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.options.size" : {
|
"workspace.options.size" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:79", "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:107", "src/uxbox/main/ui/workspace/sidebar/options/frame.cljs:101" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/frame.cljs:102", "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:110" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Size",
|
"en" : "Size",
|
||||||
"fr" : "Taille"
|
"fr" : "Taille"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.options.size-presets" : {
|
"workspace.options.size-presets" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/frame.cljs:83" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/frame.cljs:84" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Size presets"
|
"en" : "Size presets"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.options.stroke" : {
|
"workspace.options.stroke" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:109", "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:173" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:111", "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:175" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Stroke",
|
"en" : "Stroke",
|
||||||
"fr" : null
|
"fr" : null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.options.stroke.center" : {
|
"workspace.options.stroke.center" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:159" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:161" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Center"
|
"en" : "Center"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.options.stroke.dashed" : {
|
"workspace.options.stroke.dashed" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:167" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:169" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Dashed",
|
"en" : "Dashed",
|
||||||
"fr" : "Tiré"
|
"fr" : "Tiré"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.options.stroke.dotted" : {
|
"workspace.options.stroke.dotted" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:166" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:168" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Dotted",
|
"en" : "Dotted",
|
||||||
"fr" : "Pointillé"
|
"fr" : "Pointillé"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.options.stroke.inner" : {
|
"workspace.options.stroke.inner" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:160" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:162" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Inside"
|
"en" : "Inside"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.options.stroke.mixed" : {
|
"workspace.options.stroke.mixed" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:168" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:170" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Mixed",
|
"en" : "Mixed",
|
||||||
"fr" : "Mixte"
|
"fr" : "Mixte"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.options.stroke.outer" : {
|
"workspace.options.stroke.outer" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:161" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:163" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Outside"
|
"en" : "Outside"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.options.stroke.solid" : {
|
"workspace.options.stroke.solid" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:165" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:167" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Solid",
|
"en" : "Solid",
|
||||||
"fr" : "Solide"
|
"fr" : "Solide"
|
||||||
|
@ -1242,7 +1264,7 @@
|
||||||
"unused" : true
|
"unused" : true
|
||||||
},
|
},
|
||||||
"workspace.options.use-play-button" : {
|
"workspace.options.use-play-button" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:47" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs:54" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Use the play button at the header to run the prototype view."
|
"en" : "Use the play button at the header to run the prototype view."
|
||||||
}
|
}
|
||||||
|
@ -1366,7 +1388,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace.viewport.click-to-close-path" : {
|
"workspace.viewport.click-to-close-path" : {
|
||||||
"used-in" : [ "src/uxbox/main/ui/workspace/drawarea.cljs:360" ],
|
"used-in" : [ "src/uxbox/main/ui/workspace/drawarea.cljs:357" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
"en" : "Click to close the path"
|
"en" : "Click to close the path"
|
||||||
}
|
}
|
||||||
|
|
|
@ -591,6 +591,13 @@
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.element-set-content .custom-select.input-option {
|
||||||
|
border-top: none;
|
||||||
|
border-left: none;
|
||||||
|
border-right: none;
|
||||||
|
margin-left: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
.element-set-content .grid-option-main {
|
.element-set-content .grid-option-main {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 0.5rem 0;
|
padding: 0.5rem 0;
|
||||||
|
@ -626,7 +633,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid-option-main-actions {
|
.grid-option-main-actions {
|
||||||
|
@ -661,9 +667,9 @@
|
||||||
.btn-options {
|
.btn-options {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: 1px solid $color-black;
|
border: 1px solid $color-black;
|
||||||
background: #1F1F1F;
|
background: $color-gray-60;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
color: #B1B2B5;
|
color: $color-gray-20;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
@ -673,8 +679,13 @@
|
||||||
margin-right: 0.5rem;
|
margin-right: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:not([disabled]):hover {
|
||||||
background: $color-primary;
|
background: $color-primary;
|
||||||
color: $color-black;
|
color: $color-black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&[disabled] {
|
||||||
|
opacity: 0.4;
|
||||||
|
cursor: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,8 @@
|
||||||
:element-options
|
:element-options
|
||||||
:rules
|
:rules
|
||||||
:dynamic-alignment
|
:dynamic-alignment
|
||||||
:layouts})
|
:display-grid
|
||||||
|
:snap-grid})
|
||||||
|
|
||||||
(s/def ::options-mode #{:design :prototype})
|
(s/def ::options-mode #{:design :prototype})
|
||||||
|
|
||||||
|
@ -1493,13 +1494,35 @@
|
||||||
;; Layouts
|
;; Layouts
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(defonce default-layout-params
|
||||||
|
{:square {:size 16
|
||||||
|
:color {:value "#59B9E2"
|
||||||
|
:opacity 0.9}}
|
||||||
|
|
||||||
|
:column {:size 12
|
||||||
|
:type :stretch
|
||||||
|
:item-width nil
|
||||||
|
:gutter 8
|
||||||
|
:margin 0
|
||||||
|
:color {:value "#DE4762"
|
||||||
|
:opacity 0.1}}
|
||||||
|
:row {:size 12
|
||||||
|
:type :stretch
|
||||||
|
:item-height nil
|
||||||
|
:gutter 8
|
||||||
|
:margin 0
|
||||||
|
:color {:value "#DE4762"
|
||||||
|
:opacity 0.1}}})
|
||||||
|
|
||||||
(defn add-frame-layout [frame-id]
|
(defn add-frame-layout [frame-id]
|
||||||
(ptk/reify ::set-frame-layout
|
(ptk/reify ::set-frame-layout
|
||||||
dwc/IBatchedChange
|
dwc/IBatchedChange
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [pid (:current-page-id state)
|
(let [pid (:current-page-id state)
|
||||||
default-params {:size 16 :color {:value "#59B9E2" :opacity 0.9}}
|
default-params (or
|
||||||
|
(get-in state [:workspace-data pid :options :saved-layouts :square])
|
||||||
|
(:square default-layout-params))
|
||||||
prop-path [:workspace-data pid :objects frame-id :layouts]
|
prop-path [:workspace-data pid :objects frame-id :layouts]
|
||||||
layout {:type :square
|
layout {:type :square
|
||||||
:params default-params
|
:params default-params
|
||||||
|
@ -1528,14 +1551,13 @@
|
||||||
|
|
||||||
(defn set-default-layout [type params]
|
(defn set-default-layout [type params]
|
||||||
(ptk/reify ::set-default-layout
|
(ptk/reify ::set-default-layout
|
||||||
dwc/IBatchedChange
|
ptk/WatchEvent
|
||||||
|
(watch [_ state stream]
|
||||||
;; TODO: Save into the backend
|
(rx/of (dwc/commit-changes [{:type :set-option
|
||||||
ptk/UpdateEvent
|
:option [:saved-layouts type]
|
||||||
(update [_ state]
|
:value params}]
|
||||||
(->
|
[]
|
||||||
state
|
{:commit-local? true})))))
|
||||||
(assoc-in [:workspace-page :options :saved-layouts type] params)))))
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Exports
|
;; Exports
|
||||||
|
|
|
@ -42,12 +42,6 @@
|
||||||
(def workspace-page
|
(def workspace-page
|
||||||
(l/derived :workspace-page st/state))
|
(l/derived :workspace-page st/state))
|
||||||
|
|
||||||
(def workspace-page-options
|
|
||||||
(l/derived :options workspace-page))
|
|
||||||
|
|
||||||
(def workspace-saved-layouts
|
|
||||||
(l/derived :saved-layouts workspace-page-options))
|
|
||||||
|
|
||||||
(def workspace-page-id
|
(def workspace-page-id
|
||||||
(l/derived :id workspace-page))
|
(l/derived :id workspace-page))
|
||||||
|
|
||||||
|
@ -74,6 +68,13 @@
|
||||||
(get-in % [:workspace-data page-id]))
|
(get-in % [:workspace-data page-id]))
|
||||||
(l/derived st/state)))
|
(l/derived st/state)))
|
||||||
|
|
||||||
|
(def workspace-page-options
|
||||||
|
(l/derived :options workspace-data))
|
||||||
|
|
||||||
|
(def workspace-saved-layouts
|
||||||
|
(l/derived :saved-layouts workspace-page-options))
|
||||||
|
|
||||||
|
|
||||||
(def workspace-objects
|
(def workspace-objects
|
||||||
(l/derived :objects workspace-data))
|
(l/derived :objects workspace-data))
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
|
|
||||||
(def ^:private snap-accuracy 5)
|
(def ^:private snap-accuracy 5)
|
||||||
|
|
||||||
(defn- remove-from-snap-points [ids-to-remove]
|
(defn- remove-from-snap-points [remove-id?]
|
||||||
(fn [query-result]
|
(fn [query-result]
|
||||||
(->> query-result
|
(->> query-result
|
||||||
(map (fn [[value data]] [value (remove (comp ids-to-remove second) data)]))
|
(map (fn [[value data]] [value (remove (comp remove-id? second) data)]))
|
||||||
(filter (fn [[_ data]] (not (empty? data)))))))
|
(filter (fn [[_ data]] (not (empty? data)))))))
|
||||||
|
|
||||||
(defn- flatten-to-points
|
(defn- flatten-to-points
|
||||||
|
@ -90,24 +90,32 @@
|
||||||
|
|
||||||
(defn closest-snap-point
|
(defn closest-snap-point
|
||||||
[page-id shapes layout point]
|
[page-id shapes layout point]
|
||||||
(if (layout :dynamic-alignment)
|
(let [frame-id (snap-frame-id shapes)
|
||||||
(let [frame-id (snap-frame-id shapes)
|
filter-shapes (into #{} (map :id shapes))
|
||||||
filter-shapes (into #{} (map :id shapes))]
|
filter-shapes (fn [id] (if (= id :layout)
|
||||||
(->> (closest-snap page-id frame-id [point] filter-shapes)
|
(or (not (contains? layout :display-grid))
|
||||||
(rx/map #(gpt/add point %))))
|
(not (contains? layout :snap-grid)))
|
||||||
(rx/of point)))
|
(or (filter-shapes id)
|
||||||
|
(not (contains? layout :dynamic-alignment)))))]
|
||||||
|
(->> (closest-snap page-id frame-id [point] filter-shapes)
|
||||||
|
(rx/map #(gpt/add point %))
|
||||||
|
(rx/map gpt/round))))
|
||||||
|
|
||||||
(defn closest-snap-move
|
(defn closest-snap-move
|
||||||
[page-id shapes layout movev]
|
[page-id shapes layout movev]
|
||||||
(if (layout :dynamic-alignment)
|
(let [frame-id (snap-frame-id shapes)
|
||||||
(let [frame-id (snap-frame-id shapes)
|
filter-shapes (into #{} (map :id shapes))
|
||||||
filter-shapes (into #{} (map :id shapes))
|
filter-shapes (fn [id] (if (= id :layout)
|
||||||
shapes-points (->> shapes
|
(or (not (contains? layout :display-grid))
|
||||||
;; Unroll all the possible snap-points
|
(not (contains? layout :snap-grid)))
|
||||||
(mapcat (partial sp/shape-snap-points))
|
(or (filter-shapes id)
|
||||||
|
(not (contains? layout :dynamic-alignment)))))
|
||||||
|
shapes-points (->> shapes
|
||||||
|
;; Unroll all the possible snap-points
|
||||||
|
(mapcat (partial sp/shape-snap-points))
|
||||||
|
|
||||||
;; Move the points in the translation vector
|
;; Move the points in the translation vector
|
||||||
(map #(gpt/add % movev)))]
|
(map #(gpt/add % movev)))]
|
||||||
(->> (closest-snap page-id frame-id shapes-points filter-shapes)
|
(->> (closest-snap page-id frame-id shapes-points filter-shapes)
|
||||||
(rx/map #(gpt/add movev %))))
|
(rx/map #(gpt/add movev %))
|
||||||
(rx/of movev)))
|
(rx/map gpt/round))))
|
||||||
|
|
|
@ -72,42 +72,42 @@
|
||||||
:on-close #(reset! show-menu? false)}
|
:on-close #(reset! show-menu? false)}
|
||||||
[:ul.menu
|
[:ul.menu
|
||||||
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :rules))}
|
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :rules))}
|
||||||
[:span i/ruler]
|
|
||||||
[:span
|
[:span
|
||||||
(if (contains? layout :rules)
|
(if (contains? layout :rules)
|
||||||
(t locale "workspace.header.menu.hide-rules")
|
(t locale "workspace.header.menu.hide-rules")
|
||||||
(t locale "workspace.header.menu.show-rules"))]]
|
(t locale "workspace.header.menu.show-rules"))]]
|
||||||
|
|
||||||
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :grid))}
|
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :display-grid))}
|
||||||
[:span i/grid]
|
|
||||||
[:span
|
[:span
|
||||||
(if (contains? layout :grid)
|
(if (contains? layout :display-grid)
|
||||||
(t locale "workspace.header.menu.hide-grid")
|
(t locale "workspace.header.menu.hide-grid")
|
||||||
(t locale "workspace.header.menu.show-grid"))]]
|
(t locale "workspace.header.menu.show-grid"))]]
|
||||||
|
|
||||||
|
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :snap-grid))}
|
||||||
|
[:span
|
||||||
|
(if (contains? layout :snap-grid)
|
||||||
|
(t locale "workspace.header.menu.disable-snap-grid")
|
||||||
|
(t locale "workspace.header.menu.enable-snap-grid"))]]
|
||||||
|
|
||||||
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :sitemap :layers))}
|
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :sitemap :layers))}
|
||||||
[:span i/layers]
|
|
||||||
[:span
|
[:span
|
||||||
(if (or (contains? layout :sitemap) (contains? layout :layers))
|
(if (or (contains? layout :sitemap) (contains? layout :layers))
|
||||||
(t locale "workspace.header.menu.hide-layers")
|
(t locale "workspace.header.menu.hide-layers")
|
||||||
(t locale "workspace.header.menu.show-layers"))]]
|
(t locale "workspace.header.menu.show-layers"))]]
|
||||||
|
|
||||||
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :colorpalette))}
|
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :colorpalette))}
|
||||||
[:span i/palette]
|
|
||||||
[:span
|
[:span
|
||||||
(if (contains? layout :colorpalette)
|
(if (contains? layout :colorpalette)
|
||||||
(t locale "workspace.header.menu.hide-palette")
|
(t locale "workspace.header.menu.hide-palette")
|
||||||
(t locale "workspace.header.menu.show-palette"))]]
|
(t locale "workspace.header.menu.show-palette"))]]
|
||||||
|
|
||||||
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :libraries))}
|
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :libraries))}
|
||||||
[:span i/icon-set]
|
|
||||||
[:span
|
[:span
|
||||||
(if (contains? layout :libraries)
|
(if (contains? layout :libraries)
|
||||||
(t locale "workspace.header.menu.hide-libraries")
|
(t locale "workspace.header.menu.hide-libraries")
|
||||||
(t locale "workspace.header.menu.show-libraries"))]]
|
(t locale "workspace.header.menu.show-libraries"))]]
|
||||||
|
|
||||||
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :dynamic-alignment))}
|
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :dynamic-alignment))}
|
||||||
[:span i/shape-halign-left]
|
|
||||||
[:span
|
[:span
|
||||||
(if (contains? layout :dynamic-alignment)
|
(if (contains? layout :dynamic-alignment)
|
||||||
(t locale "workspace.header.menu.disable-dynamic-alignment")
|
(t locale "workspace.header.menu.disable-dynamic-alignment")
|
||||||
|
|
|
@ -19,26 +19,27 @@
|
||||||
(let [{:keys [color size] :as params} (-> layout :params)
|
(let [{:keys [color size] :as params} (-> layout :params)
|
||||||
{color-value :value color-opacity :opacity} (-> layout :params :color)
|
{color-value :value color-opacity :opacity} (-> layout :params :color)
|
||||||
{frame-width :width frame-height :height :keys [x y]} frame]
|
{frame-width :width frame-height :height :keys [x y]} frame]
|
||||||
[:g.layout
|
(when (> size 0)
|
||||||
[:*
|
[:g.layout
|
||||||
(for [xs (range size frame-width size)]
|
[:*
|
||||||
[:line {:key (str (:id frame) "-y-" xs)
|
(for [xs (range size frame-width size)]
|
||||||
:x1 (+ x xs)
|
[:line {:key (str (:id frame) "-y-" xs)
|
||||||
:y1 y
|
:x1 (+ x xs)
|
||||||
:x2 (+ x xs)
|
:y1 y
|
||||||
:y2 (+ y frame-height)
|
:x2 (+ x xs)
|
||||||
:style {:stroke color-value
|
:y2 (+ y frame-height)
|
||||||
:stroke-opacity color-opacity
|
:style {:stroke color-value
|
||||||
:stroke-width (str (/ 1 zoom))}}])
|
:stroke-opacity color-opacity
|
||||||
(for [ys (range size frame-height size)]
|
:stroke-width (str (/ 1 zoom))}}])
|
||||||
[:line {:key (str (:id frame) "-x-" ys)
|
(for [ys (range size frame-height size)]
|
||||||
:x1 x
|
[:line {:key (str (:id frame) "-x-" ys)
|
||||||
:y1 (+ y ys)
|
:x1 x
|
||||||
:x2 (+ x frame-width)
|
:y1 (+ y ys)
|
||||||
:y2 (+ y ys)
|
:x2 (+ x frame-width)
|
||||||
:style {:stroke color-value
|
:y2 (+ y ys)
|
||||||
:stroke-opacity color-opacity
|
:style {:stroke color-value
|
||||||
:stroke-width (str (/ 1 zoom))}}])]]))
|
:stroke-opacity color-opacity
|
||||||
|
:stroke-width (str (/ 1 zoom))}}])]])))
|
||||||
|
|
||||||
(mf/defc flex-layout [{:keys [key frame zoom layout]}]
|
(mf/defc flex-layout [{:keys [key frame zoom layout]}]
|
||||||
(let [{color-value :value color-opacity :opacity} (-> layout :params :color)]
|
(let [{color-value :value color-opacity :opacity} (-> layout :params :color)]
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
[:div.advanced-options {}
|
[:div.advanced-options {}
|
||||||
children]]))
|
children]]))
|
||||||
|
|
||||||
(mf/defc layout-options [{:keys [layout default-layout-params on-change on-remove]}]
|
(mf/defc layout-options [{:keys [layout default-layout-params on-change on-remove on-save-layout]}]
|
||||||
(let [state (mf/use-state {:show-advanced-options false
|
(let [state (mf/use-state {:show-advanced-options false
|
||||||
:changes {}})
|
:changes {}})
|
||||||
{:keys [type display params] :as layout} (d/deep-merge layout (:changes @state))
|
{:keys [type display params] :as layout} (d/deep-merge layout (:changes @state))
|
||||||
|
@ -68,7 +68,15 @@
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(let [change-fn (apply handle-change keys)]
|
(let [change-fn (apply handle-change keys)]
|
||||||
(-> event dom/get-target dom/get-value parse-integer change-fn))))
|
(-> event dom/get-target dom/get-value parse-integer change-fn))))
|
||||||
]
|
|
||||||
|
handle-use-default (fn []
|
||||||
|
(emit-changes! #(hash-map :params ((:type layout) default-layout-params))))
|
||||||
|
handle-set-as-default (fn []
|
||||||
|
(let [current-layout (d/deep-merge layout (-> @state :changes))]
|
||||||
|
(on-save-layout current-layout)))
|
||||||
|
|
||||||
|
is-default (= (->> @state :changes (d/deep-merge layout) :params)
|
||||||
|
(->> layout :type default-layout-params))]
|
||||||
|
|
||||||
[:div.grid-option
|
[:div.grid-option
|
||||||
[:div.grid-option-main
|
[:div.grid-option-main
|
||||||
|
@ -85,7 +93,7 @@
|
||||||
(if (= type :square)
|
(if (= type :square)
|
||||||
[:div.input-element.pixels
|
[:div.input-element.pixels
|
||||||
[:input.input-text {:type "number"
|
[:input.input-text {:type "number"
|
||||||
:min "0"
|
:min "1"
|
||||||
:no-validate true
|
:no-validate true
|
||||||
:value (:size params)
|
:value (:size params)
|
||||||
:on-change (handle-change-event :params :size)}]]
|
:on-change (handle-change-event :params :size)}]]
|
||||||
|
@ -102,6 +110,8 @@
|
||||||
:on-close toggle-advanced-options}
|
:on-close toggle-advanced-options}
|
||||||
(when (= :square type)
|
(when (= :square type)
|
||||||
[:& input-row {:label "Size"
|
[:& input-row {:label "Size"
|
||||||
|
:class "pixels"
|
||||||
|
:min 1
|
||||||
:value (:size params)
|
:value (:size params)
|
||||||
:on-change (handle-change :params :size)}])
|
:on-change (handle-change :params :size)}])
|
||||||
|
|
||||||
|
@ -128,52 +138,38 @@
|
||||||
|
|
||||||
(when (= :row type)
|
(when (= :row type)
|
||||||
[:& input-row {:label "Height"
|
[:& input-row {:label "Height"
|
||||||
|
:class "pixels"
|
||||||
:value (or (:item-height params) "")
|
:value (or (:item-height params) "")
|
||||||
:on-change (handle-change :params :item-height)}])
|
:on-change (handle-change :params :item-height)}])
|
||||||
|
|
||||||
(when (= :column type)
|
(when (= :column type)
|
||||||
[:& input-row {:label "Width"
|
[:& input-row {:label "Width"
|
||||||
|
:class "pixels"
|
||||||
:value (or (:item-width params) "")
|
:value (or (:item-width params) "")
|
||||||
:on-change (handle-change :params :item-width)}])
|
:on-change (handle-change :params :item-width)}])
|
||||||
|
|
||||||
(when (#{:row :column} type)
|
(when (#{:row :column} type)
|
||||||
[:*
|
[:*
|
||||||
[:& input-row {:label "Gutter"
|
[:& input-row {:label "Gutter"
|
||||||
|
:class "pixels"
|
||||||
:value (:gutter params)
|
:value (:gutter params)
|
||||||
:on-change (handle-change :params :gutter)}]
|
:on-change (handle-change :params :gutter)}]
|
||||||
[:& input-row {:label "Margin"
|
[:& input-row {:label "Margin"
|
||||||
|
:class "pixels"
|
||||||
:value (:margin params)
|
:value (:margin params)
|
||||||
:on-change (handle-change :params :margin)}]])
|
:on-change (handle-change :params :margin)}]])
|
||||||
|
|
||||||
[:& color-row {:value (:color params)
|
[:& color-row {:value (:color params)
|
||||||
:on-change (handle-change :params :color)}]
|
:on-change (handle-change :params :color)}]
|
||||||
[:div.row-flex
|
[:div.row-flex
|
||||||
[:button.btn-options "Use default"]
|
[:button.btn-options {:disabled is-default
|
||||||
[:button.btn-options "Set as default"]]]]))
|
:on-click handle-use-default} "Use default"]
|
||||||
|
[:button.btn-options {:disabled is-default
|
||||||
(defonce ^:private default-layout-params
|
:on-click handle-set-as-default} "Set as default"]]]]))
|
||||||
{:square {:size 16
|
|
||||||
:color {:value "#59B9E2"
|
|
||||||
:opacity 0.9}}
|
|
||||||
|
|
||||||
:column {:size 12
|
|
||||||
:type :stretch
|
|
||||||
:item-width nil
|
|
||||||
:gutter 8
|
|
||||||
:margin 0
|
|
||||||
:color {:value "#DE4762"
|
|
||||||
:opacity 0.1}}
|
|
||||||
:row {:size 12
|
|
||||||
:type :stretch
|
|
||||||
:item-height nil
|
|
||||||
:gutter 8
|
|
||||||
:margin 0
|
|
||||||
:color {:value "#DE4762"
|
|
||||||
:opacity 0.1}}})
|
|
||||||
|
|
||||||
(mf/defc frame-layouts [{:keys [shape]}]
|
(mf/defc frame-layouts [{:keys [shape]}]
|
||||||
(let [id (:id shape)
|
(let [id (:id shape)
|
||||||
default-layout-params (merge default-layout-params (mf/deref refs/workspace-saved-layouts))
|
default-layout-params (merge dw/default-layout-params (mf/deref refs/workspace-saved-layouts))
|
||||||
handle-create-layout #(st/emit! (dw/add-frame-layout id))
|
handle-create-layout #(st/emit! (dw/add-frame-layout id))
|
||||||
handle-remove-layout (fn [index] #(st/emit! (dw/remove-frame-layout id index)))
|
handle-remove-layout (fn [index] #(st/emit! (dw/remove-frame-layout id index)))
|
||||||
handle-edit-layout (fn [index] #(st/emit! (dw/set-frame-layout id index %)))
|
handle-edit-layout (fn [index] #(st/emit! (dw/set-frame-layout id index %)))
|
||||||
|
|
|
@ -10,95 +10,14 @@
|
||||||
(ns uxbox.main.ui.workspace.sidebar.options.page
|
(ns uxbox.main.ui.workspace.sidebar.options.page
|
||||||
"Page options menu entries."
|
"Page options menu entries."
|
||||||
(:require
|
(:require
|
||||||
[cuerdas.core :as str]
|
|
||||||
[rumext.alpha :as mf]
|
[rumext.alpha :as mf]
|
||||||
[okulary.core :as l]
|
[okulary.core :as l]
|
||||||
[uxbox.common.data :as d]
|
[uxbox.main.refs :as refs]))
|
||||||
[uxbox.main.ui.icons :as i]
|
|
||||||
[uxbox.main.data.workspace :as dw]
|
|
||||||
[uxbox.main.refs :as refs]
|
|
||||||
[uxbox.main.store :as st]
|
|
||||||
[uxbox.main.ui.modal :as modal]
|
|
||||||
[uxbox.main.ui.workspace.colorpicker :refer [colorpicker-modal]]
|
|
||||||
[uxbox.util.dom :as dom]
|
|
||||||
[uxbox.util.i18n :refer [tr]]))
|
|
||||||
|
|
||||||
(def default-options
|
|
||||||
"Default data for page metadata."
|
|
||||||
{:grid-x 10
|
|
||||||
:grid-y 10
|
|
||||||
:grid-color "#cccccc"})
|
|
||||||
|
|
||||||
(def options-iref
|
(def options-iref
|
||||||
(l/derived :options refs/workspace-data))
|
(l/derived :options refs/workspace-data))
|
||||||
|
|
||||||
(mf/defc grid-options
|
|
||||||
{:wrap [mf/memo]}
|
|
||||||
[props]
|
|
||||||
(let [options (->> (mf/deref options-iref)
|
|
||||||
(merge default-options))
|
|
||||||
on-x-change
|
|
||||||
(fn [event]
|
|
||||||
(let [value (-> (dom/get-target event)
|
|
||||||
(dom/get-value)
|
|
||||||
(d/parse-integer 0))]
|
|
||||||
(st/emit! (dw/update-options {:grid-x value}))))
|
|
||||||
|
|
||||||
on-y-change
|
|
||||||
(fn [event]
|
|
||||||
(let [value (-> (dom/get-target event)
|
|
||||||
(dom/get-value)
|
|
||||||
(d/parse-integer 0))]
|
|
||||||
(st/emit! (dw/update-options {:grid-y value}))))
|
|
||||||
|
|
||||||
change-color
|
|
||||||
(fn [color]
|
|
||||||
(st/emit! (dw/update-options {:grid-color color})))
|
|
||||||
|
|
||||||
on-color-input-change
|
|
||||||
(fn [event]
|
|
||||||
(let [input (dom/get-target event)
|
|
||||||
value (dom/get-value input)]
|
|
||||||
(when (dom/valid? input)
|
|
||||||
(change-color value))))
|
|
||||||
|
|
||||||
show-color-picker
|
|
||||||
(fn [event]
|
|
||||||
(let [x (.-clientX event)
|
|
||||||
y (.-clientY event)
|
|
||||||
props {:x x :y y
|
|
||||||
:transparent? true
|
|
||||||
:default "#cccccc"
|
|
||||||
:attr :grid-color
|
|
||||||
:on-change change-color}]
|
|
||||||
(modal/show! colorpicker-modal props)))]
|
|
||||||
[:div.element-set
|
|
||||||
[:div.element-set-title (tr "workspace.options.grid-options")]
|
|
||||||
[:div.element-set-content
|
|
||||||
[:div.row-flex
|
|
||||||
[:span.element-set-subtitle (tr "workspace.options.size")]
|
|
||||||
[:div.input-element.pixels
|
|
||||||
[:input.input-text {:type "number"
|
|
||||||
:value (:grid-x options)
|
|
||||||
:on-change on-x-change}]]
|
|
||||||
[:div.input-element.pixels
|
|
||||||
[:input.input-text {:type "number"
|
|
||||||
:value (:grid-y options)
|
|
||||||
:on-change on-y-change}]]]
|
|
||||||
[:div.row-flex.color-data
|
|
||||||
[:span.element-set-subtitle (tr "workspace.options.color")]
|
|
||||||
[:span.color-th {:style {:background-color (:grid-color options)}
|
|
||||||
:on-click show-color-picker}]
|
|
||||||
[:div.color-info
|
|
||||||
[:input {:default-value (:grid-color options)
|
|
||||||
:ref (fn [el]
|
|
||||||
(when el
|
|
||||||
(set! (.-value el) (:grid-color options))))
|
|
||||||
:pattern "^#(?:[0-9a-fA-F]{3}){1,2}$"
|
|
||||||
:on-change on-color-input-change}]]]]]))
|
|
||||||
|
|
||||||
(mf/defc options
|
(mf/defc options
|
||||||
[{:keys [page] :as props}]
|
;; TODO: Define properties for page
|
||||||
[:div
|
[{:keys [page] :as props}])
|
||||||
[:& grid-options {:page page}]])
|
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,8 @@
|
||||||
(/ 100)))
|
(/ 100)))
|
||||||
|
|
||||||
(mf/defc color-row [{:keys [value on-change]}]
|
(mf/defc color-row [{:keys [value on-change]}]
|
||||||
(let [state (mf/use-state value)
|
(let [value (or value {:value "#FFFFFF" :opacity 1})
|
||||||
|
state (mf/use-state value)
|
||||||
change-color (fn [color]
|
change-color (fn [color]
|
||||||
(let [update-color (fn [state] (assoc state :value color))]
|
(let [update-color (fn [state] (assoc state :value color))]
|
||||||
(swap! state update-color)
|
(swap! state update-color)
|
||||||
|
@ -65,6 +66,10 @@
|
||||||
string->opacity
|
string->opacity
|
||||||
change-opacity))]
|
change-opacity))]
|
||||||
|
|
||||||
|
(mf/use-effect
|
||||||
|
(mf/deps value)
|
||||||
|
#(reset! state value))
|
||||||
|
|
||||||
[:div.row-flex.color-data
|
[:div.row-flex.color-data
|
||||||
[:span.color-th
|
[:span.color-th
|
||||||
{:style {:background-color (-> @state :value)}
|
{:style {:background-color (-> @state :value)}
|
||||||
|
@ -88,3 +93,4 @@
|
||||||
:value (-> @state :opacity opacity->string)
|
:value (-> @state :opacity opacity->string)
|
||||||
:step "1"
|
:step "1"
|
||||||
:on-change handle-opacity-change}]]))
|
:on-change handle-opacity-change}]]))
|
||||||
|
|
||||||
|
|
|
@ -14,17 +14,19 @@
|
||||||
[uxbox.main.ui.components.select :refer [select]]
|
[uxbox.main.ui.components.select :refer [select]]
|
||||||
[uxbox.util.dom :as dom]))
|
[uxbox.util.dom :as dom]))
|
||||||
|
|
||||||
(mf/defc input-row [{:keys [label options value on-change]}]
|
(mf/defc input-row [{:keys [label options value class min max on-change]}]
|
||||||
[:div.row-flex.input-row
|
(let [handle-change (fn [value] (when (and (or (not min) (>= value min)) (or (not max) (<= value max)))
|
||||||
[:span.element-set-subtitle label]
|
(on-change value)))]
|
||||||
[:div.input-element
|
[:div.row-flex.input-row
|
||||||
(if options
|
[:span.element-set-subtitle label]
|
||||||
[:& select {:default-value value
|
[:div.input-element {:class class}
|
||||||
:class "input-option"
|
(if options
|
||||||
:options options
|
[:& select {:default-value value
|
||||||
:on-change on-change}]
|
:class "input-option"
|
||||||
[:input.input-text
|
:options options
|
||||||
{:placeholder label
|
:on-change on-change}]
|
||||||
:type "number"
|
[:input.input-text
|
||||||
:on-change #(-> % dom/get-target dom/get-value d/parse-integer on-change)
|
{:placeholder label
|
||||||
:value value}])]])
|
:type "number"
|
||||||
|
:on-change #(-> % dom/get-target dom/get-value d/parse-integer handle-change)
|
||||||
|
:value value}])]]))
|
||||||
|
|
|
@ -80,12 +80,17 @@
|
||||||
:point point
|
:point point
|
||||||
:zoom zoom}])]))]))
|
:zoom zoom}])]))]))
|
||||||
|
|
||||||
(mf/defc snap-feedback [{:keys []}]
|
(mf/defc snap-feedback [{:keys [layout]}]
|
||||||
(let [page-id (mf/deref refs/workspace-page-id)
|
(let [page-id (mf/deref refs/workspace-page-id)
|
||||||
selected (mf/deref refs/selected-shapes)
|
selected (mf/deref refs/selected-shapes)
|
||||||
selected-shapes (mf/deref (refs/objects-by-id selected))
|
selected-shapes (mf/deref (refs/objects-by-id selected))
|
||||||
drawing (mf/deref refs/current-drawing-shape)
|
drawing (mf/deref refs/current-drawing-shape)
|
||||||
filter-shapes (mf/deref refs/selected-shapes-with-children)
|
filter-shapes (mf/deref refs/selected-shapes-with-children)
|
||||||
|
filter-shapes (fn [id] (if (= id :layout)
|
||||||
|
(or (not (contains? layout :display-grid))
|
||||||
|
(not (contains? layout :snap-grid)))
|
||||||
|
(or (filter-shapes id)
|
||||||
|
(not (contains? layout :dynamic-alignment)))))
|
||||||
current-transform (mf/deref refs/current-transform)
|
current-transform (mf/deref refs/current-transform)
|
||||||
snap-data (mf/deref refs/workspace-snap-data)
|
snap-data (mf/deref refs/workspace-snap-data)
|
||||||
shapes (if drawing [drawing] selected-shapes)
|
shapes (if drawing [drawing] selected-shapes)
|
||||||
|
|
|
@ -386,10 +386,10 @@
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
:modifiers (:modifiers local)}])
|
:modifiers (:modifiers local)}])
|
||||||
|
|
||||||
(when (contains? layout :layouts)
|
(when (contains? layout :display-grid)
|
||||||
[:& layout-display {:zoom zoom}])
|
[:& layout-display {:zoom zoom}])
|
||||||
|
|
||||||
[:& snap-feedback]
|
[:& snap-feedback {:layout layout}]
|
||||||
|
|
||||||
(when tooltip
|
(when tooltip
|
||||||
[:& cursor-tooltip {:zoom zoom :tooltip tooltip}])]
|
[:& cursor-tooltip {:zoom zoom :tooltip tooltip}])]
|
||||||
|
|
|
@ -74,11 +74,12 @@
|
||||||
(case type
|
(case type
|
||||||
:square (let [{:keys [x y width height]} shape
|
:square (let [{:keys [x y width height]} shape
|
||||||
size (-> params :size)]
|
size (-> params :size)]
|
||||||
(if (= coord :x)
|
(when (> size 0)
|
||||||
(mapcat #(vector (gpt/point (+ x %) y)
|
(if (= coord :x)
|
||||||
(gpt/point (+ x %) (+ y height))) (range size width size))
|
(mapcat #(vector (gpt/point (+ x %) y)
|
||||||
(mapcat #(vector (gpt/point x (+ y %))
|
(gpt/point (+ x %) (+ y height))) (range size width size))
|
||||||
(gpt/point (+ x width) (+ y %))) (range size height size))))
|
(mapcat #(vector (gpt/point x (+ y %))
|
||||||
|
(gpt/point (+ x width) (+ y %))) (range size height size)))))
|
||||||
:column (when (= coord :x) (->> (layout-rects shape layout)
|
:column (when (= coord :x) (->> (layout-rects shape layout)
|
||||||
(mapcat layout-rect-points)))
|
(mapcat layout-rect-points)))
|
||||||
|
|
||||||
|
|
|
@ -151,11 +151,12 @@
|
||||||
|
|
||||||
(defn round
|
(defn round
|
||||||
"Change the precision of the point coordinates."
|
"Change the precision of the point coordinates."
|
||||||
[{:keys [x y] :as p} decimanls]
|
([point] (round point 0))
|
||||||
(assert (point? p))
|
([{:keys [x y] :as p} decimanls]
|
||||||
(assert (number? decimanls))
|
(assert (point? p))
|
||||||
(Point. (mth/precision x decimanls)
|
(assert (number? decimanls))
|
||||||
(mth/precision y decimanls)))
|
(Point. (mth/precision x decimanls)
|
||||||
|
(mth/precision y decimanls))))
|
||||||
|
|
||||||
(defn transform
|
(defn transform
|
||||||
"Transform a point applying a matrix transfomation."
|
"Transform a point applying a matrix transfomation."
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue