mirror of
https://github.com/penpot/penpot.git
synced 2026-09-10 14:09:17 +00:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
ec021d944d
@ -72,6 +72,7 @@ on-premises instances** that want to keep up to date.
|
|||||||
- Fix button width [Taiga #11394](https://tree.taiga.io/project/penpot/issue/11394)
|
- Fix button width [Taiga #11394](https://tree.taiga.io/project/penpot/issue/11394)
|
||||||
- Fix mixed letter spacing and line height [Taiga #11178](https://tree.taiga.io/project/penpot/issue/11178)
|
- Fix mixed letter spacing and line height [Taiga #11178](https://tree.taiga.io/project/penpot/issue/11178)
|
||||||
- Fix snap nodes shortcut [Taiga #11054](https://tree.taiga.io/project/penpot/issue/11054)
|
- Fix snap nodes shortcut [Taiga #11054](https://tree.taiga.io/project/penpot/issue/11054)
|
||||||
|
- Fix changing a text property in a text layer does not unapply the previously applied token in the same property [Taiga #11337}(https://tree.taiga.io/project/penpot/issue/11337)
|
||||||
|
|
||||||
## 2.7.2
|
## 2.7.2
|
||||||
|
|
||||||
|
|||||||
@ -161,7 +161,6 @@
|
|||||||
(contains? (meta changes) ::file-data)
|
(contains? (meta changes) ::file-data)
|
||||||
"Call (with-file-data) before using this function"))
|
"Call (with-file-data) before using this function"))
|
||||||
|
|
||||||
|
|
||||||
(defn- lookup-objects
|
(defn- lookup-objects
|
||||||
[changes]
|
[changes]
|
||||||
(let [data (::file-data (meta changes))]
|
(let [data (::file-data (meta changes))]
|
||||||
|
|||||||
@ -16,19 +16,30 @@
|
|||||||
[app.common.types.pages-list :as ctpl]
|
[app.common.types.pages-list :as ctpl]
|
||||||
[app.common.types.shape.interactions :as ctsi]
|
[app.common.types.shape.interactions :as ctsi]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
|
[app.common.types.text :as ctt]
|
||||||
[app.common.types.token :as cto]
|
[app.common.types.token :as cto]
|
||||||
[app.common.uuid :as uuid]))
|
[app.common.uuid :as uuid]
|
||||||
|
[clojure.set :as set]))
|
||||||
|
|
||||||
(defn- generate-unapply-tokens
|
(defn- generate-unapply-tokens
|
||||||
"When updating attributes that have a token applied, we must unapply it, because the value
|
"When updating attributes that have a token applied, we must unapply it, because the value
|
||||||
of the attribute now has been given directly, and does not come from the token."
|
of the attribute now has been given directly, and does not come from the token."
|
||||||
[changes objects changed-sub-attr]
|
[changes objects changed-sub-attr]
|
||||||
(let [mod-obj-changes (->> (:redo-changes changes)
|
(let [new-objects (pcb/get-objects changes)
|
||||||
|
mod-obj-changes (->> (:redo-changes changes)
|
||||||
(filter #(= (:type %) :mod-obj)))
|
(filter #(= (:type %) :mod-obj)))
|
||||||
|
|
||||||
|
text-changed-attrs
|
||||||
|
(fn [shape]
|
||||||
|
(let [new-shape (get new-objects (:id shape))
|
||||||
|
attrs (ctt/get-diff-attrs (:content shape) (:content new-shape))]
|
||||||
|
(apply set/union (map cto/shape-attr->token-attrs attrs))))
|
||||||
|
|
||||||
check-attr (fn [shape changes attr]
|
check-attr (fn [shape changes attr]
|
||||||
(let [tokens (get shape :applied-tokens {})
|
(let [tokens (get shape :applied-tokens {})
|
||||||
token-attrs (cto/shape-attr->token-attrs attr changed-sub-attr)]
|
token-attrs (if (or (not= (:type shape) :text) (not= attr :content))
|
||||||
|
(cto/shape-attr->token-attrs attr changed-sub-attr)
|
||||||
|
(text-changed-attrs shape))]
|
||||||
(if (some #(contains? tokens %) token-attrs)
|
(if (some #(contains? tokens %) token-attrs)
|
||||||
(pcb/update-shapes changes [(:id shape)] #(cto/unapply-token-id % token-attrs))
|
(pcb/update-shapes changes [(:id shape)] #(cto/unapply-token-id % token-attrs))
|
||||||
changes)))
|
changes)))
|
||||||
|
|||||||
@ -37,8 +37,6 @@
|
|||||||
(merge shape
|
(merge shape
|
||||||
text-params))))
|
text-params))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defn add-frame
|
(defn add-frame
|
||||||
[file frame-label & {:keys [] :as params}]
|
[file frame-label & {:keys [] :as params}]
|
||||||
;; Generated shape tree:
|
;; Generated shape tree:
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
[app.common.files.helpers :as cfh]
|
[app.common.files.helpers :as cfh]
|
||||||
[app.common.test-helpers.files :as thf]
|
[app.common.test-helpers.files :as thf]
|
||||||
[app.common.test-helpers.ids-map :as thi]
|
[app.common.test-helpers.ids-map :as thi]
|
||||||
|
[app.common.text :as txt]
|
||||||
[app.common.types.color :as ctc]
|
[app.common.types.color :as ctc]
|
||||||
[app.common.types.container :as ctn]
|
[app.common.types.container :as ctn]
|
||||||
[app.common.types.pages-list :as ctpl]
|
[app.common.types.pages-list :as ctpl]
|
||||||
@ -81,6 +82,21 @@
|
|||||||
(:id page)
|
(:id page)
|
||||||
#(ctst/set-shape % (ctn/set-shape-attr shape attr val)))))))
|
#(ctst/set-shape % (ctn/set-shape-attr shape attr val)))))))
|
||||||
|
|
||||||
|
(defn update-shape-text
|
||||||
|
[file shape-label attr val & {:keys [page-label]}]
|
||||||
|
(let [page (if page-label
|
||||||
|
(thf/get-page file page-label)
|
||||||
|
(thf/current-page file))
|
||||||
|
shape (ctst/get-shape page (thi/id shape-label))]
|
||||||
|
(update file :data
|
||||||
|
(fn [file-data]
|
||||||
|
(ctpl/update-page file-data
|
||||||
|
(:id page)
|
||||||
|
#(ctst/set-shape % (txt/update-text-content shape
|
||||||
|
txt/is-content-node?
|
||||||
|
d/txt-merge
|
||||||
|
{attr val})))))))
|
||||||
|
|
||||||
(defn sample-library-color
|
(defn sample-library-color
|
||||||
[label & {:keys [name path color opacity gradient image]}]
|
[label & {:keys [name path color opacity gradient image]}]
|
||||||
(-> {:id (thi/new-id! label)
|
(-> {:id (thi/new-id! label)
|
||||||
|
|||||||
@ -470,8 +470,6 @@
|
|||||||
"Given a content and a set of points return all the segments in the path
|
"Given a content and a set of points return all the segments in the path
|
||||||
that uses the points"
|
that uses the points"
|
||||||
[content points]
|
[content points]
|
||||||
(assert (impl/path-data? content) "expected path data instance")
|
|
||||||
|
|
||||||
(let [point-set (set points)]
|
(let [point-set (set points)]
|
||||||
(loop [result (transient [])
|
(loop [result (transient [])
|
||||||
prev-point nil
|
prev-point nil
|
||||||
|
|||||||
@ -11,9 +11,12 @@
|
|||||||
|
|
||||||
(defn- compare-text-content
|
(defn- compare-text-content
|
||||||
"Given two content text structures, conformed by maps and vectors,
|
"Given two content text structures, conformed by maps and vectors,
|
||||||
compare them, and returns a set with the type of differences.
|
compare them, and returns a set with the differences info.
|
||||||
The possibilities are :text-content-text :text-content-attribute and :text-content-structure."
|
If the structures are equal, it returns an empty set. If the structure
|
||||||
[a b]
|
has changed, it returns :text-content-structure. There are two
|
||||||
|
callbacks to specify what to return when there is a text change with
|
||||||
|
the same structure, and when attributes change."
|
||||||
|
[a b {:keys [text-cb attribute-cb] :as callbacks}]
|
||||||
(cond
|
(cond
|
||||||
;; If a and b are equal, there is no diff
|
;; If a and b are equal, there is no diff
|
||||||
(= a b)
|
(= a b)
|
||||||
@ -38,18 +41,18 @@
|
|||||||
#{:text-content-structure}
|
#{:text-content-structure}
|
||||||
(into acc
|
(into acc
|
||||||
(apply set/union
|
(apply set/union
|
||||||
(map #(compare-text-content %1 %2) v1 v2))))
|
(map #(compare-text-content %1 %2 callbacks) v1 v2))))
|
||||||
|
|
||||||
;; If the key is :text, and they are different, it is a text differece
|
;; If the key is :text, and they are different, it is a text differece
|
||||||
(= k :text)
|
(= k :text)
|
||||||
(if (not= v1 v2)
|
(if (not= v1 v2)
|
||||||
(conj acc :text-content-text)
|
(text-cb acc)
|
||||||
acc)
|
acc)
|
||||||
|
|
||||||
:else
|
:else
|
||||||
;; If the key is not :text, and they are different, it is an attribute differece
|
;; If the key is not :text, and they are different, it is an attribute differece
|
||||||
(if (not= v1 v2)
|
(if (not= v1 v2)
|
||||||
(conj acc :text-content-attribute)
|
(attribute-cb acc k)
|
||||||
acc))))
|
acc))))
|
||||||
#{}
|
#{}
|
||||||
keys))
|
keys))
|
||||||
@ -57,7 +60,6 @@
|
|||||||
:else
|
:else
|
||||||
#{:text-content-structure}))
|
#{:text-content-structure}))
|
||||||
|
|
||||||
|
|
||||||
(defn equal-attrs?
|
(defn equal-attrs?
|
||||||
"Given a text structure, and a map of attrs, check that all the internal attrs in
|
"Given a text structure, and a map of attrs, check that all the internal attrs in
|
||||||
paragraphs and sentences have the same attrs"
|
paragraphs and sentences have the same attrs"
|
||||||
@ -79,10 +81,15 @@
|
|||||||
(defn get-diff-type
|
(defn get-diff-type
|
||||||
"Given two content text structures, conformed by maps and vectors,
|
"Given two content text structures, conformed by maps and vectors,
|
||||||
compare them, and returns a set with the type of differences.
|
compare them, and returns a set with the type of differences.
|
||||||
The possibilities are :text-content-text :text-content-attribute,
|
The possibilities are
|
||||||
:text-content-structure and :text-content-structure-same-attrs."
|
:text-content-text
|
||||||
|
:text-content-attribute,
|
||||||
|
:text-content-structure
|
||||||
|
:text-content-structure-same-attrs."
|
||||||
[a b]
|
[a b]
|
||||||
(let [diff-type (compare-text-content a b)]
|
(let [diff-type (compare-text-content a b
|
||||||
|
{:text-cb (fn [acc] (conj acc :text-content-text))
|
||||||
|
:attribute-cb (fn [acc _] (conj acc :text-content-attribute))})]
|
||||||
(if-not (contains? diff-type :text-content-structure)
|
(if-not (contains? diff-type :text-content-structure)
|
||||||
diff-type
|
diff-type
|
||||||
(let [;; get attrs of the first paragraph of the first paragraph-set
|
(let [;; get attrs of the first paragraph of the first paragraph-set
|
||||||
@ -92,6 +99,24 @@
|
|||||||
#{:text-content-structure :text-content-structure-same-attrs}
|
#{:text-content-structure :text-content-structure-same-attrs}
|
||||||
diff-type)))))
|
diff-type)))))
|
||||||
|
|
||||||
|
(defn get-diff-attrs
|
||||||
|
"Given two content text structures, conformed by maps and vectors,
|
||||||
|
compare them, and returns a set with the attributes that have changed.
|
||||||
|
This is independent of the text structure, so if the structure changes
|
||||||
|
but the attributes are the same, it will return an empty set."
|
||||||
|
[a b]
|
||||||
|
(let [diff-attrs (compare-text-content a b
|
||||||
|
{:text-cb identity
|
||||||
|
:attribute-cb (fn [acc attr] (conj acc attr))})]
|
||||||
|
(if-not (contains? diff-attrs :text-content-structure)
|
||||||
|
diff-attrs
|
||||||
|
(let [;; get attrs of the first paragraph of the first paragraph-set
|
||||||
|
attrs (get-first-paragraph-text-attrs a)]
|
||||||
|
(if (and (equal-attrs? a attrs)
|
||||||
|
(equal-attrs? b attrs))
|
||||||
|
#{}
|
||||||
|
(disj diff-attrs :text-content-structure))))))
|
||||||
|
|
||||||
;; TODO We know that there are cases that the blocks of texts are separated
|
;; TODO We know that there are cases that the blocks of texts are separated
|
||||||
;; differently: ["one" " " "two"], ["one " "two"], ["one" " two"]
|
;; differently: ["one" " " "two"], ["one " "two"], ["one" " two"]
|
||||||
;; so this won't work for 100% of the situations. But it's good enough for now,
|
;; so this won't work for 100% of the situations. But it's good enough for now,
|
||||||
@ -116,7 +141,6 @@
|
|||||||
:else
|
:else
|
||||||
true))
|
true))
|
||||||
|
|
||||||
|
|
||||||
(defn copy-text-keys
|
(defn copy-text-keys
|
||||||
"Given two equal content text structures, deep copy all the keys :text
|
"Given two equal content text structures, deep copy all the keys :text
|
||||||
from origin to destiny"
|
from origin to destiny"
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
(ns common-tests.logic.token-apply-test
|
(ns common-tests.logic.token-apply-test
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
[app.common.files.changes-builder :as pcb]
|
[app.common.files.changes-builder :as pcb]
|
||||||
[app.common.logic.shapes :as cls]
|
[app.common.logic.shapes :as cls]
|
||||||
[app.common.test-helpers.compositions :as tho]
|
[app.common.test-helpers.compositions :as tho]
|
||||||
@ -13,6 +14,7 @@
|
|||||||
[app.common.test-helpers.ids-map :as thi]
|
[app.common.test-helpers.ids-map :as thi]
|
||||||
[app.common.test-helpers.shapes :as ths]
|
[app.common.test-helpers.shapes :as ths]
|
||||||
[app.common.test-helpers.tokens :as tht]
|
[app.common.test-helpers.tokens :as tht]
|
||||||
|
[app.common.text :as txt]
|
||||||
[app.common.types.container :as ctn]
|
[app.common.types.container :as ctn]
|
||||||
[app.common.types.token :as cto]
|
[app.common.types.token :as cto]
|
||||||
[app.common.types.tokens-lib :as ctob]
|
[app.common.types.tokens-lib :as ctob]
|
||||||
@ -53,7 +55,8 @@
|
|||||||
(ctob/make-token :name "token-dimensions"
|
(ctob/make-token :name "token-dimensions"
|
||||||
:type :dimensions
|
:type :dimensions
|
||||||
:value 100))))
|
:value 100))))
|
||||||
(tho/add-frame :frame1)))
|
(tho/add-frame :frame1)
|
||||||
|
(tho/add-text :text1 "Hello World")))
|
||||||
|
|
||||||
(defn- apply-all-tokens
|
(defn- apply-all-tokens
|
||||||
[file]
|
[file]
|
||||||
@ -64,7 +67,8 @@
|
|||||||
(tht/apply-token-to-shape :frame1 "token-stroke-width" [:stroke-width] [:stroke-width] 2)
|
(tht/apply-token-to-shape :frame1 "token-stroke-width" [:stroke-width] [:stroke-width] 2)
|
||||||
(tht/apply-token-to-shape :frame1 "token-color" [:stroke-color] [:stroke-color] "#00ff00")
|
(tht/apply-token-to-shape :frame1 "token-color" [:stroke-color] [:stroke-color] "#00ff00")
|
||||||
(tht/apply-token-to-shape :frame1 "token-color" [:fill] [:fill] "#00ff00")
|
(tht/apply-token-to-shape :frame1 "token-color" [:fill] [:fill] "#00ff00")
|
||||||
(tht/apply-token-to-shape :frame1 "token-dimensions" [:width :height] [:width :height] 100)))
|
(tht/apply-token-to-shape :frame1 "token-dimensions" [:width :height] [:width :height] 100)
|
||||||
|
(tht/apply-token-to-shape :text1 "token-color" [:fill] [:fill] "#00ff00")))
|
||||||
|
|
||||||
(t/deftest apply-tokens-to-shape
|
(t/deftest apply-tokens-to-shape
|
||||||
(let [;; ==== Setup
|
(let [;; ==== Setup
|
||||||
@ -171,6 +175,7 @@
|
|||||||
(apply-all-tokens))
|
(apply-all-tokens))
|
||||||
page (thf/current-page file)
|
page (thf/current-page file)
|
||||||
frame1 (ths/get-shape file :frame1)
|
frame1 (ths/get-shape file :frame1)
|
||||||
|
text1 (ths/get-shape file :text1)
|
||||||
|
|
||||||
;; ==== Action
|
;; ==== Action
|
||||||
changes (-> (-> (pcb/empty-changes nil)
|
changes (-> (-> (pcb/empty-changes nil)
|
||||||
@ -190,13 +195,25 @@
|
|||||||
(ctn/set-shape-attr :width 0)
|
(ctn/set-shape-attr :width 0)
|
||||||
(ctn/set-shape-attr :height 0)))
|
(ctn/set-shape-attr :height 0)))
|
||||||
(:objects page)
|
(:objects page)
|
||||||
|
{})
|
||||||
|
(cls/generate-update-shapes [(:id text1)]
|
||||||
|
(fn [shape]
|
||||||
|
(txt/update-text-content
|
||||||
|
shape
|
||||||
|
txt/is-content-node?
|
||||||
|
d/txt-merge
|
||||||
|
{:fills (ths/sample-fills-color :fill-color "#fabada")}))
|
||||||
|
(:objects page)
|
||||||
{}))
|
{}))
|
||||||
|
|
||||||
file' (thf/apply-changes file changes)
|
file' (thf/apply-changes file changes)
|
||||||
|
|
||||||
;; ==== Get
|
;; ==== Get
|
||||||
frame1' (ths/get-shape file' :frame1)
|
frame1' (ths/get-shape file' :frame1)
|
||||||
applied-tokens' (:applied-tokens frame1')]
|
text1' (ths/get-shape file' :text1)
|
||||||
|
applied-tokens-frame' (:applied-tokens frame1')
|
||||||
|
applied-tokens-text' (:applied-tokens text1')]
|
||||||
|
|
||||||
;; ==== Check
|
;; ==== Check
|
||||||
(t/is (= (count applied-tokens') 0))))
|
(t/is (= (count applied-tokens-frame') 0))
|
||||||
|
(t/is (= (count applied-tokens-text') 0))))
|
||||||
@ -29,11 +29,12 @@
|
|||||||
#(conj % line)))
|
#(conj % line)))
|
||||||
|
|
||||||
(t/deftest test-get-diff-type
|
(t/deftest test-get-diff-type
|
||||||
(let [diff-text (cttx/get-diff-type content-base content-changed-text)
|
(let [diff-text (cttx/get-diff-type content-base content-changed-text)
|
||||||
diff-attr (cttx/get-diff-type content-base content-changed-attr)
|
diff-attr (cttx/get-diff-type content-base content-changed-attr)
|
||||||
diff-both (cttx/get-diff-type content-base content-changed-both)
|
diff-both (cttx/get-diff-type content-base content-changed-both)
|
||||||
diff-structure (cttx/get-diff-type content-base content-changed-structure)
|
diff-structure (cttx/get-diff-type content-base content-changed-structure)
|
||||||
diff-structure-same-attrs (cttx/get-diff-type content-base content-changed-structure-same-attrs)]
|
diff-structure-same-attrs (cttx/get-diff-type content-base content-changed-structure-same-attrs)]
|
||||||
|
|
||||||
(t/is (= #{:text-content-text} diff-text))
|
(t/is (= #{:text-content-text} diff-text))
|
||||||
(t/is (= #{:text-content-attribute} diff-attr))
|
(t/is (= #{:text-content-attribute} diff-attr))
|
||||||
(t/is (= #{:text-content-text :text-content-attribute} diff-both))
|
(t/is (= #{:text-content-text :text-content-attribute} diff-both))
|
||||||
@ -41,6 +42,20 @@
|
|||||||
(t/is (= #{:text-content-structure :text-content-structure-same-attrs} diff-structure-same-attrs))))
|
(t/is (= #{:text-content-structure :text-content-structure-same-attrs} diff-structure-same-attrs))))
|
||||||
|
|
||||||
|
|
||||||
|
(t/deftest test-get-diff-attrs
|
||||||
|
(let [attrs-text (cttx/get-diff-attrs content-base content-changed-text)
|
||||||
|
attrs-attr (cttx/get-diff-attrs content-base content-changed-attr)
|
||||||
|
attrs-both (cttx/get-diff-attrs content-base content-changed-both)
|
||||||
|
attrs-structure (cttx/get-diff-attrs content-base content-changed-structure)
|
||||||
|
attrs-structure-same-attrs (cttx/get-diff-attrs content-base content-changed-structure-same-attrs)]
|
||||||
|
|
||||||
|
(t/is (= #{} attrs-text))
|
||||||
|
(t/is (= #{:font-size} attrs-attr))
|
||||||
|
(t/is (= #{:font-size} attrs-both))
|
||||||
|
(t/is (= #{} attrs-structure))
|
||||||
|
(t/is (= #{} attrs-structure-same-attrs))))
|
||||||
|
|
||||||
|
|
||||||
(t/deftest test-equal-structure
|
(t/deftest test-equal-structure
|
||||||
(t/is (true? (cttx/equal-structure? content-base content-changed-text)))
|
(t/is (true? (cttx/equal-structure? content-base content-changed-text)))
|
||||||
(t/is (true? (cttx/equal-structure? content-base content-changed-attr)))
|
(t/is (true? (cttx/equal-structure? content-base content-changed-attr)))
|
||||||
|
|||||||
@ -96,7 +96,7 @@
|
|||||||
(watch [_ _ _]
|
(watch [_ _ _]
|
||||||
(rx/of
|
(rx/of
|
||||||
(case type
|
(case type
|
||||||
:path (path/handle-new-shape)
|
:path (path/handle-drawing)
|
||||||
:curve (curve/handle-drawing)
|
:curve (curve/handle-drawing)
|
||||||
(box/handle-drawing type))))))
|
(box/handle-drawing type))))))
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
[app.main.data.workspace.path.undo :as undo]))
|
[app.main.data.workspace.path.undo :as undo]))
|
||||||
|
|
||||||
;; Drawing
|
;; Drawing
|
||||||
(dm/export drawing/handle-new-shape)
|
(dm/export drawing/handle-drawing)
|
||||||
(dm/export drawing/start-path-from-point)
|
(dm/export drawing/start-path-from-point)
|
||||||
(dm/export drawing/close-path-drag-start)
|
(dm/export drawing/close-path-drag-start)
|
||||||
(dm/export drawing/change-edit-mode)
|
(dm/export drawing/change-edit-mode)
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
(defn init-path []
|
(defn init-path []
|
||||||
(ptk/reify ::init-path))
|
(ptk/data-event ::init-path {}))
|
||||||
|
|
||||||
(defn clean-edit-state
|
(defn clean-edit-state
|
||||||
[state]
|
[state]
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
(ns app.main.data.workspace.path.drawing
|
(ns app.main.data.workspace.path.drawing
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.geom.shapes.flex-layout :as gsl]
|
[app.common.geom.shapes.flex-layout :as gsl]
|
||||||
@ -30,21 +31,40 @@
|
|||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
|
(declare close-path-drag-end)
|
||||||
|
(declare check-changed-content)
|
||||||
(declare change-edit-mode)
|
(declare change-edit-mode)
|
||||||
|
|
||||||
(defn preview-next-point [{:keys [x y shift?]}]
|
(defn- end-path-event?
|
||||||
|
[event]
|
||||||
|
(let [type (ptk/type event)]
|
||||||
|
(or
|
||||||
|
(= type ::common/finish-path)
|
||||||
|
(= type :app.main.data.workspace.path.shortcuts/esc-pressed)
|
||||||
|
(= type :app.main.data.workspace.common/clear-edition-mode)
|
||||||
|
(= type :app.main.data.workspace.edition/clear-edition-mode)
|
||||||
|
(= type :app.main.data.workspace/finalize-page)
|
||||||
|
(= event :interrupt) ;; ESC
|
||||||
|
(and ^boolean (mse/mouse-event? event)
|
||||||
|
^boolean (mse/mouse-double-click-event? event)))))
|
||||||
|
|
||||||
|
(defn preview-next-point
|
||||||
|
[{:keys [x y shift?]}]
|
||||||
(ptk/reify ::preview-next-point
|
(ptk/reify ::preview-next-point
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [id (st/get-path-id state)
|
(let [id (st/get-path-id state)
|
||||||
fix-angle? shift?
|
fix-angle? shift?
|
||||||
last-point (get-in state [:workspace-local :edit-path id :last-point])
|
last-point (get-in state [:workspace-local :edit-path id :last-point])
|
||||||
position (cond-> (gpt/point x y)
|
position (cond-> (gpt/point x y)
|
||||||
fix-angle? (path.helpers/position-fixed-angle last-point))
|
fix-angle? (path.helpers/position-fixed-angle last-point))
|
||||||
shape (st/get-path state)
|
shape (st/get-path state)
|
||||||
{:keys [last-point prev-handler]} (get-in state [:workspace-local :edit-path id])
|
|
||||||
command (path.segment/next-node shape position last-point prev-handler)]
|
{:keys [last-point prev-handler]}
|
||||||
(assoc-in state [:workspace-local :edit-path id :preview] command)))))
|
(get-in state [:workspace-local :edit-path id])
|
||||||
|
|
||||||
|
segment (path.segment/next-node shape position last-point prev-handler)]
|
||||||
|
(assoc-in state [:workspace-local :edit-path id :preview] segment)))))
|
||||||
|
|
||||||
(defn add-node
|
(defn add-node
|
||||||
[{:keys [x y shift?]}]
|
[{:keys [x y shift?]}]
|
||||||
@ -121,8 +141,6 @@
|
|||||||
(rx/of (preview-next-point handler)
|
(rx/of (preview-next-point handler)
|
||||||
(undo/merge-head))))))
|
(undo/merge-head))))))
|
||||||
|
|
||||||
(declare close-path-drag-end)
|
|
||||||
|
|
||||||
(defn close-path-drag-start
|
(defn close-path-drag-start
|
||||||
[position]
|
[position]
|
||||||
(ptk/reify ::close-path-drag-start
|
(ptk/reify ::close-path-drag-start
|
||||||
@ -141,8 +159,7 @@
|
|||||||
(rx/take-until
|
(rx/take-until
|
||||||
(rx/merge
|
(rx/merge
|
||||||
(mse/drag-stopper stream)
|
(mse/drag-stopper stream)
|
||||||
(->> stream
|
(rx/filter end-path-event? stream))))]
|
||||||
(rx/filter helpers/end-path-event?)))))]
|
|
||||||
|
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of (add-node position))
|
(rx/of (add-node position))
|
||||||
@ -166,8 +183,7 @@
|
|||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [stopper (rx/merge
|
(let [stopper (rx/merge
|
||||||
(mse/drag-stopper stream)
|
(mse/drag-stopper stream)
|
||||||
(->> stream
|
(rx/filter end-path-event? stream))
|
||||||
(rx/filter helpers/end-path-event?)))
|
|
||||||
|
|
||||||
drag-events (->> (streams/position-stream state)
|
drag-events (->> (streams/position-stream state)
|
||||||
(rx/map #(drag-handler %))
|
(rx/map #(drag-handler %))
|
||||||
@ -189,18 +205,17 @@
|
|||||||
(defn make-drag-stream
|
(defn make-drag-stream
|
||||||
[state stream down-event]
|
[state stream down-event]
|
||||||
|
|
||||||
(dm/assert!
|
(assert (gpt/point? down-event)
|
||||||
"should be a pointer"
|
"should be a point instance")
|
||||||
(gpt/point? down-event))
|
|
||||||
|
|
||||||
(let [stopper (rx/merge
|
(let [stopper (rx/merge
|
||||||
(mse/drag-stopper stream)
|
(mse/drag-stopper stream)
|
||||||
(->> stream
|
(rx/filter end-path-event? stream))
|
||||||
(rx/filter helpers/end-path-event?)))
|
|
||||||
|
|
||||||
drag-events (->> (streams/position-stream state)
|
drag-events
|
||||||
(rx/map #(drag-handler %))
|
(->> (streams/position-stream state)
|
||||||
(rx/take-until stopper))]
|
(rx/map #(drag-handler %))
|
||||||
|
(rx/take-until stopper))]
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of (add-node down-event))
|
(rx/of (add-node down-event))
|
||||||
(streams/drag-stream
|
(streams/drag-stream
|
||||||
@ -208,9 +223,9 @@
|
|||||||
drag-events
|
drag-events
|
||||||
(rx/of (finish-drag)))))))
|
(rx/of (finish-drag)))))))
|
||||||
|
|
||||||
(defn handle-drawing
|
(defn- start-edition
|
||||||
[_id]
|
[_id]
|
||||||
(ptk/reify ::handle-drawing
|
(ptk/reify ::start-edition
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [id (st/get-path-id state)]
|
(let [id (st/get-path-id state)]
|
||||||
@ -218,38 +233,47 @@
|
|||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [mouse-down (->> stream
|
(let [mouse-down
|
||||||
(rx/filter mse/mouse-event?)
|
(->> stream
|
||||||
(rx/filter mse/mouse-down-event?))
|
(rx/filter mse/mouse-event?)
|
||||||
end-path-events (->> stream
|
(rx/filter mse/mouse-down-event?))
|
||||||
(rx/filter helpers/end-path-event?))
|
|
||||||
|
end-stream
|
||||||
|
(->> stream
|
||||||
|
(rx/filter end-path-event?)
|
||||||
|
(rx/share))
|
||||||
|
|
||||||
|
stoper-stream
|
||||||
|
(->> stream
|
||||||
|
(rx/filter (ptk/type? ::start-edition))
|
||||||
|
(rx/merge end-stream))
|
||||||
|
|
||||||
;; Mouse move preview
|
;; Mouse move preview
|
||||||
mousemove-events
|
mousemove-events
|
||||||
(->> (streams/position-stream state)
|
(->> (streams/position-stream state)
|
||||||
(rx/take-until end-path-events)
|
|
||||||
(rx/map #(preview-next-point %)))
|
(rx/map #(preview-next-point %)))
|
||||||
|
|
||||||
;; From mouse down we can have: click, drag and double click
|
;; From mouse down we can have: click, drag and double click
|
||||||
mousedown-events
|
mousedown-events
|
||||||
(->> mouse-down
|
(->> mouse-down
|
||||||
(rx/take-until end-path-events)
|
|
||||||
;; We just ignore the mouse event and stream down the
|
;; We just ignore the mouse event and stream down the
|
||||||
;; last position event
|
;; last position event
|
||||||
(rx/with-latest-from #(-> %2) (streams/position-stream state))
|
(rx/with-latest-from #(-> %2) (streams/position-stream state))
|
||||||
;; We change to the stream that emits the first event
|
;; We change to the stream that emits the first event
|
||||||
(rx/switch-map
|
(rx/switch-map
|
||||||
#(rx/race (make-node-events-stream stream)
|
#(rx/race (make-node-events-stream stream)
|
||||||
(make-drag-stream state stream %))))]
|
(make-drag-stream state stream %)))
|
||||||
|
(rx/take-until end-stream))]
|
||||||
|
|
||||||
(rx/concat
|
(->> (rx/concat
|
||||||
(rx/of (undo/start-path-undo))
|
(rx/of (undo/start-path-undo))
|
||||||
(rx/of (common/init-path))
|
(->> (rx/merge mousemove-events
|
||||||
(rx/merge mousemove-events
|
mousedown-events)
|
||||||
mousedown-events)
|
(rx/take-until stoper-stream))
|
||||||
(rx/of (common/finish-path)))))))
|
(rx/of (ptk/data-event ::end-edition))))))))
|
||||||
|
|
||||||
(defn setup-frame []
|
(defn setup-frame
|
||||||
|
[]
|
||||||
(ptk/reify ::setup-frame
|
(ptk/reify ::setup-frame
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
@ -275,9 +299,9 @@
|
|||||||
(cond-> (some? drop-index)
|
(cond-> (some? drop-index)
|
||||||
(with-meta {:index drop-index})))))))))
|
(with-meta {:index drop-index})))))))))
|
||||||
|
|
||||||
(defn handle-new-shape-result
|
(defn- handle-drawing-end
|
||||||
[shape-id]
|
[shape-id]
|
||||||
(ptk/reify ::handle-new-shape-result
|
(ptk/reify ::handle-drawing-end
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [content (dm/get-in state [:workspace-drawing :object :content])]
|
(let [content (dm/get-in state [:workspace-drawing :object :content])]
|
||||||
@ -299,8 +323,8 @@
|
|||||||
(change-edit-mode :draw))
|
(change-edit-mode :draw))
|
||||||
(rx/of (dwdc/handle-finish-drawing)))))))
|
(rx/of (dwdc/handle-finish-drawing)))))))
|
||||||
|
|
||||||
(defn handle-new-shape
|
(defn handle-drawing
|
||||||
"Creates a new path shape"
|
"Hanndle the start of drawing new path shape"
|
||||||
[]
|
[]
|
||||||
(ptk/reify ::handle-new-shape
|
(ptk/reify ::handle-new-shape
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
@ -312,16 +336,17 @@
|
|||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [shape-id (dm/get-in state [:workspace-drawing :object :id])]
|
(let [shape-id (dm/get-in state [:workspace-drawing :object :id])]
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of (handle-drawing shape-id))
|
(rx/of (start-edition shape-id))
|
||||||
(->> stream
|
(->> stream
|
||||||
(rx/filter (ptk/type? ::common/finish-path))
|
(rx/filter (ptk/type? ::end-edition))
|
||||||
(rx/take 1)
|
(rx/take 1)
|
||||||
(rx/observe-on :async)
|
(rx/observe-on :async)
|
||||||
(rx/map #(handle-new-shape-result shape-id))))))))
|
(rx/map (partial handle-drawing-end shape-id))))))))
|
||||||
|
|
||||||
(declare check-changed-content)
|
(declare start-draw-mode*)
|
||||||
|
|
||||||
(defn start-draw-mode []
|
(defn start-draw-mode
|
||||||
|
[]
|
||||||
(ptk/reify ::start-draw-mode
|
(ptk/reify ::start-draw-mode
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
@ -332,21 +357,59 @@
|
|||||||
(update-in state [:workspace-local :edit-path id] assoc :old-content content)
|
(update-in state [:workspace-local :edit-path id] assoc :old-content content)
|
||||||
state)))
|
state)))
|
||||||
|
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ _ _]
|
||||||
|
(rx/of (start-draw-mode*)))))
|
||||||
|
|
||||||
|
(defn start-draw-mode*
|
||||||
|
[]
|
||||||
|
(ptk/reify ::start-draw-mode*
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [id (get-in state [:workspace-local :edition])
|
(let [local (get state :workspace-local)
|
||||||
edit-mode (get-in state [:workspace-local :edit-path id :edit-mode])]
|
id (get local :edition)
|
||||||
(if (= :draw edit-mode)
|
mode (dm/get-in local [:edit-path id :edit-mode])]
|
||||||
|
|
||||||
|
(if (= :draw mode)
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of (dwsh/update-shapes [id] path/convert-to-path))
|
(rx/of (dwsh/update-shapes [id] path/convert-to-path))
|
||||||
(rx/of (handle-drawing id))
|
(rx/of (start-edition id))
|
||||||
(->> stream
|
(->> stream
|
||||||
(rx/filter (ptk/type? ::common/finish-path))
|
(rx/filter (ptk/type? ::end-edition))
|
||||||
(rx/take 1)
|
(rx/take 1)
|
||||||
(rx/map check-changed-content)))
|
(rx/mapcat (fn [_]
|
||||||
|
(rx/of (check-changed-content)
|
||||||
|
(start-draw-mode*))))))
|
||||||
(rx/empty))))))
|
(rx/empty))))))
|
||||||
|
|
||||||
(defn check-changed-content []
|
(defn change-edit-mode
|
||||||
|
[mode]
|
||||||
|
(ptk/reify ::change-edit-mode
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(if-let [id (dm/get-in state [:workspace-local :edition])]
|
||||||
|
(d/update-in-when state [:workspace-local :edit-path id] assoc :edit-mode mode)
|
||||||
|
state))
|
||||||
|
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ state _]
|
||||||
|
(when-let [id (dm/get-in state [:workspace-local :edition])]
|
||||||
|
(let [mode (dm/get-in state [:workspace-local :edit-path id :edit-mode])]
|
||||||
|
(case mode
|
||||||
|
:move (rx/of (common/finish-path))
|
||||||
|
:draw (rx/of (start-draw-mode))
|
||||||
|
(rx/empty)))))))
|
||||||
|
|
||||||
|
(defn reset-last-handler
|
||||||
|
[]
|
||||||
|
(ptk/reify ::reset-last-handler
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(let [id (st/get-path-id state)]
|
||||||
|
(assoc-in state [:workspace-local :edit-path id :prev-handler] nil)))))
|
||||||
|
|
||||||
|
(defn check-changed-content
|
||||||
|
[]
|
||||||
(ptk/reify ::check-changed-content
|
(ptk/reify ::check-changed-content
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
@ -355,36 +418,15 @@
|
|||||||
old-content (get-in state [:workspace-local :edit-path id :old-content])
|
old-content (get-in state [:workspace-local :edit-path id :old-content])
|
||||||
mode (get-in state [:workspace-local :edit-path id :edit-mode])
|
mode (get-in state [:workspace-local :edit-path id :edit-mode])
|
||||||
empty-content? (empty? content)]
|
empty-content? (empty? content)]
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
(and (not= content old-content) (not empty-content?)) (rx/of (changes/save-path-content))
|
(and (not= content old-content) (not empty-content?))
|
||||||
(= mode :draw) (rx/of :interrupt)
|
(rx/of (changes/save-path-content))
|
||||||
:else (rx/of
|
|
||||||
(common/finish-path)
|
|
||||||
(dwdc/clear-drawing)))))))
|
|
||||||
|
|
||||||
(defn change-edit-mode
|
(= mode :draw)
|
||||||
[mode]
|
(rx/of :interrupt)
|
||||||
(ptk/reify ::change-edit-mode
|
|
||||||
ptk/UpdateEvent
|
|
||||||
(update [_ state]
|
|
||||||
(let [id (get-in state [:workspace-local :edition])]
|
|
||||||
(cond-> state
|
|
||||||
id (assoc-in [:workspace-local :edit-path id :edit-mode] mode))))
|
|
||||||
|
|
||||||
ptk/WatchEvent
|
|
||||||
(watch [_ state _]
|
|
||||||
(let [id (st/get-path-id state)]
|
|
||||||
(cond
|
|
||||||
(and id (= :move mode)) (rx/of (common/finish-path))
|
|
||||||
(and id (= :draw mode)) (rx/of (start-draw-mode))
|
|
||||||
:else (rx/empty))))))
|
|
||||||
|
|
||||||
(defn reset-last-handler
|
|
||||||
[]
|
|
||||||
(ptk/reify ::reset-last-handler
|
|
||||||
ptk/UpdateEvent
|
|
||||||
(update [_ state]
|
|
||||||
(let [id (st/get-path-id state)]
|
|
||||||
(-> state
|
|
||||||
(assoc-in [:workspace-local :edit-path id :prev-handler] nil))))))
|
|
||||||
|
|
||||||
|
:else
|
||||||
|
(rx/of
|
||||||
|
(common/finish-path)
|
||||||
|
(dwdc/clear-drawing)))))))
|
||||||
|
|||||||
@ -10,22 +10,7 @@
|
|||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
[app.common.types.path :as path]
|
[app.common.types.path :as path]
|
||||||
[app.common.types.path.helpers :as path.helpers]
|
[app.common.types.path.helpers :as path.helpers]
|
||||||
[app.common.types.path.segment :as path.segment]
|
[app.common.types.path.segment :as path.segment]))
|
||||||
[app.main.data.workspace.path.common :as common]
|
|
||||||
[app.util.mouse :as mse]
|
|
||||||
[potok.v2.core :as ptk]))
|
|
||||||
|
|
||||||
(defn end-path-event?
|
|
||||||
[event]
|
|
||||||
(let [type (ptk/type event)]
|
|
||||||
(or (= type ::common/finish-path)
|
|
||||||
(= type :app.main.data.workspace.path.shortcuts/esc-pressed)
|
|
||||||
(= type :app.main.data.workspace.common/clear-edition-mode)
|
|
||||||
(= type :app.main.data.workspace.edition/clear-edition-mode)
|
|
||||||
(= type :app.main.data.workspace/finalize-page)
|
|
||||||
(= event :interrupt) ;; ESC
|
|
||||||
(and ^boolean (mse/mouse-event? event)
|
|
||||||
^boolean (mse/mouse-double-click-event? event)))))
|
|
||||||
|
|
||||||
(defn append-node
|
(defn append-node
|
||||||
"Creates a new node in the path. Usually used when drawing."
|
"Creates a new node in the path. Usually used when drawing."
|
||||||
|
|||||||
@ -7,42 +7,8 @@
|
|||||||
(ns app.main.data.workspace.path.state
|
(ns app.main.data.workspace.path.state
|
||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.files.helpers :as cph]
|
|
||||||
[app.common.types.path.shape-to-path :as stp]))
|
[app.common.types.path.shape-to-path :as stp]))
|
||||||
|
|
||||||
(defn path-editing?
|
|
||||||
"Returns true if we're editing a path or creating a new one."
|
|
||||||
[{local :workspace-local
|
|
||||||
drawing :workspace-drawing}]
|
|
||||||
(let [selected (:selected local)
|
|
||||||
edition (:edition local)
|
|
||||||
|
|
||||||
drawing-obj (:object drawing)
|
|
||||||
drawing-tool (:tool drawing)
|
|
||||||
|
|
||||||
edit-path? (dm/get-in local [:edit-path edition])
|
|
||||||
|
|
||||||
shape (or drawing-obj (first selected))
|
|
||||||
shape-id (:id shape)
|
|
||||||
|
|
||||||
single? (= (count selected) 1)
|
|
||||||
editing? (and (some? shape-id)
|
|
||||||
(some? edition)
|
|
||||||
(= shape-id edition))
|
|
||||||
|
|
||||||
;; we need to check if we're drawing a new object but we're
|
|
||||||
;; not using the pencil tool.
|
|
||||||
draw-path? (and (some? drawing-obj)
|
|
||||||
(cph/path-shape? drawing-obj)
|
|
||||||
(not= :curve drawing-tool))]
|
|
||||||
|
|
||||||
(or (and ^boolean single?
|
|
||||||
^boolean editing?
|
|
||||||
(and (not (cph/text-shape? shape))
|
|
||||||
(not (cph/frame-shape? shape))))
|
|
||||||
draw-path?
|
|
||||||
edit-path?)))
|
|
||||||
|
|
||||||
(defn get-path-id
|
(defn get-path-id
|
||||||
"Retrieves the currently editing path id"
|
"Retrieves the currently editing path id"
|
||||||
[state]
|
[state]
|
||||||
|
|||||||
@ -22,9 +22,8 @@
|
|||||||
(defn initialize-viewport
|
(defn initialize-viewport
|
||||||
[{:keys [width height] :as size}]
|
[{:keys [width height] :as size}]
|
||||||
|
|
||||||
(dm/assert!
|
(assert (gpr/rect? size)
|
||||||
"expected `size` to be a rect instance"
|
"expected `size` to be a rect instance")
|
||||||
(gpr/rect? size))
|
|
||||||
|
|
||||||
(letfn [(update* [{:keys [vport] :as local}]
|
(letfn [(update* [{:keys [vport] :as local}]
|
||||||
(let [wprop (/ (:width vport) width)
|
(let [wprop (/ (:width vport) width)
|
||||||
|
|||||||
@ -8,13 +8,11 @@
|
|||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.files.helpers :as cfh]
|
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.types.path :as path]
|
[app.common.types.path :as path]
|
||||||
[app.common.types.path.helpers :as path.helpers]
|
[app.common.types.path.helpers :as path.helpers]
|
||||||
[app.common.types.path.segment :as path.segment]
|
[app.common.types.path.segment :as path.segment]
|
||||||
[app.main.data.workspace.path :as drp]
|
[app.main.data.workspace.path :as drp]
|
||||||
[app.main.refs :as refs]
|
|
||||||
[app.main.snap :as snap]
|
[app.main.snap :as snap]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
@ -24,7 +22,6 @@
|
|||||||
[app.util.keyboard :as kbd]
|
[app.util.keyboard :as kbd]
|
||||||
[clojure.set :refer [map-invert]]
|
[clojure.set :refer [map-invert]]
|
||||||
[goog.events :as events]
|
[goog.events :as events]
|
||||||
[okulary.core :as l]
|
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(def point-radius 5)
|
(def point-radius 5)
|
||||||
@ -261,18 +258,9 @@
|
|||||||
angle (gpt/angle-with-other v1 v2)]
|
angle (gpt/angle-with-other v1 v2)]
|
||||||
(<= (- 180 angle) 0.1))))
|
(<= (- 180 angle) 0.1))))
|
||||||
|
|
||||||
(defn- make-edit-path-ref [id]
|
|
||||||
(let [get-fn #(dm/get-in % [:edit-path id])]
|
|
||||||
(l/derived get-fn refs/workspace-local)))
|
|
||||||
|
|
||||||
(mf/defc path-editor*
|
(mf/defc path-editor*
|
||||||
[{:keys [shape zoom]}]
|
[{:keys [shape zoom state]}]
|
||||||
|
(let [hover-point (mf/use-state nil)
|
||||||
(let [shape-id (dm/get-prop shape :id)
|
|
||||||
edit-path-ref (mf/with-memo [shape-id]
|
|
||||||
(make-edit-path-ref shape-id))
|
|
||||||
|
|
||||||
hover-point (mf/use-state nil)
|
|
||||||
editor-ref (mf/use-ref nil)
|
editor-ref (mf/use-ref nil)
|
||||||
|
|
||||||
{:keys [edit-mode
|
{:keys [edit-mode
|
||||||
@ -286,19 +274,12 @@
|
|||||||
moving-handler
|
moving-handler
|
||||||
hover-handlers
|
hover-handlers
|
||||||
hover-points
|
hover-points
|
||||||
snap-toggled]
|
snap-toggled]}
|
||||||
:as edit-path}
|
state
|
||||||
(mf/deref edit-path-ref)
|
|
||||||
|
|
||||||
selected-points
|
selected-points
|
||||||
(or selected-points #{})
|
(or selected-points #{})
|
||||||
|
|
||||||
shape
|
|
||||||
(mf/with-memo [shape]
|
|
||||||
(cond-> shape
|
|
||||||
(not (cfh/path-shape? shape))
|
|
||||||
(path/convert-to-path)))
|
|
||||||
|
|
||||||
base-content
|
base-content
|
||||||
(get shape :content)
|
(get shape :content)
|
||||||
|
|
||||||
|
|||||||
@ -7,14 +7,12 @@
|
|||||||
(ns app.main.ui.workspace.top-toolbar
|
(ns app.main.ui.workspace.top-toolbar
|
||||||
(:require-macros [app.main.style :as stl])
|
(:require-macros [app.main.style :as stl])
|
||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.main.data.event :as ev]
|
[app.main.data.event :as ev]
|
||||||
[app.main.data.modal :as modal]
|
[app.main.data.modal :as modal]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.data.workspace.common :as dwc]
|
[app.main.data.workspace.common :as dwc]
|
||||||
[app.main.data.workspace.media :as dwm]
|
[app.main.data.workspace.media :as dwm]
|
||||||
[app.main.data.workspace.path.state :as pst]
|
|
||||||
[app.main.data.workspace.shortcuts :as sc]
|
[app.main.data.workspace.shortcuts :as sc]
|
||||||
[app.main.features :as features]
|
[app.main.features :as features]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
@ -68,26 +66,31 @@
|
|||||||
:ref ref
|
:ref ref
|
||||||
:on-selected on-selected}]]]))
|
:on-selected on-selected}]]]))
|
||||||
|
|
||||||
(def toolbar-hidden
|
(def ^:private toolbar-hidden-ref
|
||||||
(l/derived
|
(l/derived (fn [state]
|
||||||
(fn [state]
|
(let [visibility (get state :hide-toolbar)
|
||||||
(let [visibility (dm/get-in state [:workspace-local :hide-toolbar])
|
path-edit-state (get state :edit-path)
|
||||||
editing? (pst/path-editing? state)
|
|
||||||
hidden? (if editing? true visibility)]
|
|
||||||
hidden?))
|
|
||||||
st/state))
|
|
||||||
|
|
||||||
(mf/defc top-toolbar
|
selected (get state :selected)
|
||||||
{::mf/wrap [mf/memo]
|
edition (get state :edition)
|
||||||
::mf/wrap-props false}
|
single? (= (count selected) 1)
|
||||||
|
|
||||||
|
path-editing? (and single? (some? (get path-edit-state edition)))]
|
||||||
|
(if path-editing? true visibility)))
|
||||||
|
refs/workspace-local))
|
||||||
|
|
||||||
|
(mf/defc top-toolbar*
|
||||||
|
{::mf/memo true}
|
||||||
[{:keys [layout]}]
|
[{:keys [layout]}]
|
||||||
(let [selected-drawtool (mf/deref refs/selected-drawing-tool)
|
(let [drawtool (mf/deref refs/selected-drawing-tool)
|
||||||
edition (mf/deref refs/selected-edition)
|
edition (mf/deref refs/selected-edition)
|
||||||
|
|
||||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
profile (mf/deref refs/profile)
|
||||||
|
props (get profile :props)
|
||||||
|
|
||||||
rulers? (mf/deref refs/rulers?)
|
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||||
hide-toolbar? (mf/deref toolbar-hidden)
|
rulers? (mf/deref refs/rulers?)
|
||||||
|
hide-toolbar? (mf/deref toolbar-hidden-ref)
|
||||||
|
|
||||||
interrupt
|
interrupt
|
||||||
(mf/use-fn #(st/emit! :interrupt (dw/clear-edition-mode)))
|
(mf/use-fn #(st/emit! :interrupt (dw/clear-edition-mode)))
|
||||||
@ -121,8 +124,6 @@
|
|||||||
(dom/blur! (dom/get-target event))
|
(dom/blur! (dom/get-target event))
|
||||||
(st/emit! (dwc/toggle-toolbar-visibility))))
|
(st/emit! (dwc/toggle-toolbar-visibility))))
|
||||||
|
|
||||||
profile (mf/deref refs/profile)
|
|
||||||
props (get profile :props)
|
|
||||||
test-tooltip-board-text
|
test-tooltip-board-text
|
||||||
(if (not (:workspace-visited props))
|
(if (not (:workspace-visited props))
|
||||||
(tr "workspace.toolbar.frame-first-time" (sc/get-tooltip :draw-frame))
|
(tr "workspace.toolbar.frame-first-time" (sc/get-tooltip :draw-frame))
|
||||||
@ -139,7 +140,7 @@
|
|||||||
{:title (tr "workspace.toolbar.move" (sc/get-tooltip :move))
|
{:title (tr "workspace.toolbar.move" (sc/get-tooltip :move))
|
||||||
:aria-label (tr "workspace.toolbar.move" (sc/get-tooltip :move))
|
:aria-label (tr "workspace.toolbar.move" (sc/get-tooltip :move))
|
||||||
:class (stl/css-case :main-toolbar-options-button true
|
:class (stl/css-case :main-toolbar-options-button true
|
||||||
:selected (and (nil? selected-drawtool)
|
:selected (and (nil? drawtool)
|
||||||
(not edition)))
|
(not edition)))
|
||||||
:on-click interrupt}
|
:on-click interrupt}
|
||||||
i/move]]
|
i/move]]
|
||||||
@ -148,7 +149,7 @@
|
|||||||
[:button
|
[:button
|
||||||
{:title test-tooltip-board-text
|
{:title test-tooltip-board-text
|
||||||
:aria-label (tr "workspace.toolbar.frame" (sc/get-tooltip :draw-frame))
|
:aria-label (tr "workspace.toolbar.frame" (sc/get-tooltip :draw-frame))
|
||||||
:class (stl/css-case :main-toolbar-options-button true :selected (= selected-drawtool :frame))
|
:class (stl/css-case :main-toolbar-options-button true :selected (= drawtool :frame))
|
||||||
:on-click select-drawtool
|
:on-click select-drawtool
|
||||||
:data-tool "frame"
|
:data-tool "frame"
|
||||||
:data-testid "artboard-btn"}
|
:data-testid "artboard-btn"}
|
||||||
@ -157,7 +158,7 @@
|
|||||||
[:button
|
[:button
|
||||||
{:title (tr "workspace.toolbar.rect" (sc/get-tooltip :draw-rect))
|
{:title (tr "workspace.toolbar.rect" (sc/get-tooltip :draw-rect))
|
||||||
:aria-label (tr "workspace.toolbar.rect" (sc/get-tooltip :draw-rect))
|
:aria-label (tr "workspace.toolbar.rect" (sc/get-tooltip :draw-rect))
|
||||||
:class (stl/css-case :main-toolbar-options-button true :selected (= selected-drawtool :rect))
|
:class (stl/css-case :main-toolbar-options-button true :selected (= drawtool :rect))
|
||||||
:on-click select-drawtool
|
:on-click select-drawtool
|
||||||
:data-tool "rect"
|
:data-tool "rect"
|
||||||
:data-testid "rect-btn"}
|
:data-testid "rect-btn"}
|
||||||
@ -166,7 +167,7 @@
|
|||||||
[:button
|
[:button
|
||||||
{:title (tr "workspace.toolbar.ellipse" (sc/get-tooltip :draw-ellipse))
|
{:title (tr "workspace.toolbar.ellipse" (sc/get-tooltip :draw-ellipse))
|
||||||
:aria-label (tr "workspace.toolbar.ellipse" (sc/get-tooltip :draw-ellipse))
|
:aria-label (tr "workspace.toolbar.ellipse" (sc/get-tooltip :draw-ellipse))
|
||||||
:class (stl/css-case :main-toolbar-options-button true :selected (= selected-drawtool :circle))
|
:class (stl/css-case :main-toolbar-options-button true :selected (= drawtool :circle))
|
||||||
:on-click select-drawtool
|
:on-click select-drawtool
|
||||||
:data-tool "circle"
|
:data-tool "circle"
|
||||||
:data-testid "ellipse-btn"}
|
:data-testid "ellipse-btn"}
|
||||||
@ -175,7 +176,7 @@
|
|||||||
[:button
|
[:button
|
||||||
{:title (tr "workspace.toolbar.text" (sc/get-tooltip :draw-text))
|
{:title (tr "workspace.toolbar.text" (sc/get-tooltip :draw-text))
|
||||||
:aria-label (tr "workspace.toolbar.text" (sc/get-tooltip :draw-text))
|
:aria-label (tr "workspace.toolbar.text" (sc/get-tooltip :draw-text))
|
||||||
:class (stl/css-case :main-toolbar-options-button true :selected (= selected-drawtool :text))
|
:class (stl/css-case :main-toolbar-options-button true :selected (= drawtool :text))
|
||||||
:on-click select-drawtool
|
:on-click select-drawtool
|
||||||
:data-tool "text"}
|
:data-tool "text"}
|
||||||
i/text]]
|
i/text]]
|
||||||
@ -186,7 +187,7 @@
|
|||||||
[:button
|
[:button
|
||||||
{:title (tr "workspace.toolbar.curve" (sc/get-tooltip :draw-curve))
|
{:title (tr "workspace.toolbar.curve" (sc/get-tooltip :draw-curve))
|
||||||
:aria-label (tr "workspace.toolbar.curve" (sc/get-tooltip :draw-curve))
|
:aria-label (tr "workspace.toolbar.curve" (sc/get-tooltip :draw-curve))
|
||||||
:class (stl/css-case :main-toolbar-options-button true :selected (= selected-drawtool :curve))
|
:class (stl/css-case :main-toolbar-options-button true :selected (= drawtool :curve))
|
||||||
:on-click select-drawtool
|
:on-click select-drawtool
|
||||||
:data-tool "curve"
|
:data-tool "curve"
|
||||||
:data-testid "curve-btn"}
|
:data-testid "curve-btn"}
|
||||||
@ -195,7 +196,7 @@
|
|||||||
[:button
|
[:button
|
||||||
{:title (tr "workspace.toolbar.path" (sc/get-tooltip :draw-path))
|
{:title (tr "workspace.toolbar.path" (sc/get-tooltip :draw-path))
|
||||||
:aria-label (tr "workspace.toolbar.path" (sc/get-tooltip :draw-path))
|
:aria-label (tr "workspace.toolbar.path" (sc/get-tooltip :draw-path))
|
||||||
:class (stl/css-case :main-toolbar-options-button true :selected (= selected-drawtool :path))
|
:class (stl/css-case :main-toolbar-options-button true :selected (= drawtool :path))
|
||||||
:on-click select-drawtool
|
:on-click select-drawtool
|
||||||
:data-tool "path"
|
:data-tool "path"
|
||||||
:data-testid "path-btn"}
|
:data-testid "path-btn"}
|
||||||
|
|||||||
@ -12,6 +12,8 @@
|
|||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.files.helpers :as cfh]
|
[app.common.files.helpers :as cfh]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
|
[app.common.types.path :as path]
|
||||||
|
[app.common.types.shape :as cts]
|
||||||
[app.common.types.shape-tree :as ctt]
|
[app.common.types.shape-tree :as ctt]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.main.data.workspace.modifiers :as dwm]
|
[app.main.data.workspace.modifiers :as dwm]
|
||||||
@ -29,6 +31,7 @@
|
|||||||
[app.main.ui.workspace.shapes.text.text-edition-outline :refer [text-edition-outline]]
|
[app.main.ui.workspace.shapes.text.text-edition-outline :refer [text-edition-outline]]
|
||||||
[app.main.ui.workspace.shapes.text.v2-editor :as editor-v2]
|
[app.main.ui.workspace.shapes.text.v2-editor :as editor-v2]
|
||||||
[app.main.ui.workspace.shapes.text.viewport-texts-html :as stvh]
|
[app.main.ui.workspace.shapes.text.viewport-texts-html :as stvh]
|
||||||
|
[app.main.ui.workspace.top-toolbar :refer [top-toolbar*]]
|
||||||
[app.main.ui.workspace.viewport-wasm :as viewport.wasm]
|
[app.main.ui.workspace.viewport-wasm :as viewport.wasm]
|
||||||
[app.main.ui.workspace.viewport.actions :as actions]
|
[app.main.ui.workspace.viewport.actions :as actions]
|
||||||
[app.main.ui.workspace.viewport.comments :as comments]
|
[app.main.ui.workspace.viewport.comments :as comments]
|
||||||
@ -48,7 +51,7 @@
|
|||||||
[app.main.ui.workspace.viewport.selection :as selection]
|
[app.main.ui.workspace.viewport.selection :as selection]
|
||||||
[app.main.ui.workspace.viewport.snap-distances :as snap-distances]
|
[app.main.ui.workspace.viewport.snap-distances :as snap-distances]
|
||||||
[app.main.ui.workspace.viewport.snap-points :as snap-points]
|
[app.main.ui.workspace.viewport.snap-points :as snap-points]
|
||||||
[app.main.ui.workspace.viewport.top-bar :as top-bar]
|
[app.main.ui.workspace.viewport.top-bar :refer [path-edition-bar* grid-edition-bar* view-only-bar*]]
|
||||||
[app.main.ui.workspace.viewport.utils :as utils]
|
[app.main.ui.workspace.viewport.utils :as utils]
|
||||||
[app.main.ui.workspace.viewport.viewport-ref :refer [create-viewport-ref]]
|
[app.main.ui.workspace.viewport.viewport-ref :refer [create-viewport-ref]]
|
||||||
[app.main.ui.workspace.viewport.widgets :as widgets]
|
[app.main.ui.workspace.viewport.widgets :as widgets]
|
||||||
@ -88,12 +91,14 @@
|
|||||||
vport
|
vport
|
||||||
zoom
|
zoom
|
||||||
zoom-inverse
|
zoom-inverse
|
||||||
edition]} wlocal
|
edition]}
|
||||||
|
wlocal
|
||||||
|
|
||||||
{:keys [options-mode
|
{:keys [options-mode
|
||||||
tooltip
|
tooltip
|
||||||
show-distances?
|
show-distances?
|
||||||
picking-color?]} wglobal
|
picking-color?]}
|
||||||
|
wglobal
|
||||||
|
|
||||||
vbox' (mf/use-debounce 100 vbox)
|
vbox' (mf/use-debounce 100 vbox)
|
||||||
|
|
||||||
@ -122,23 +127,23 @@
|
|||||||
(not-empty))
|
(not-empty))
|
||||||
|
|
||||||
;; STATE
|
;; STATE
|
||||||
alt? (mf/use-state false)
|
alt? (mf/use-state false)
|
||||||
shift? (mf/use-state false)
|
shift? (mf/use-state false)
|
||||||
mod? (mf/use-state false)
|
mod? (mf/use-state false)
|
||||||
space? (mf/use-state false)
|
space? (mf/use-state false)
|
||||||
z? (mf/use-state false)
|
z? (mf/use-state false)
|
||||||
cursor (mf/use-state (utils/get-cursor :pointer-inner))
|
cursor (mf/use-state #(utils/get-cursor :pointer-inner))
|
||||||
hover-ids (mf/use-state nil)
|
hover-ids (mf/use-state nil)
|
||||||
hover (mf/use-state nil)
|
hover (mf/use-state nil)
|
||||||
measure-hover (mf/use-state nil)
|
measure-hover (mf/use-state nil)
|
||||||
hover-disabled? (mf/use-state false)
|
hover-disabled? (mf/use-state false)
|
||||||
hover-top-frame-id (mf/use-state nil)
|
hover-top-frame-id (mf/use-state nil)
|
||||||
frame-hover (mf/use-state nil)
|
frame-hover (mf/use-state nil)
|
||||||
active-frames (mf/use-state #{})
|
active-frames (mf/use-state #{})
|
||||||
|
|
||||||
;; REFS
|
;; REFS
|
||||||
[viewport-ref
|
[viewport-ref on-viewport-ref]
|
||||||
on-viewport-ref] (create-viewport-ref)
|
(create-viewport-ref)
|
||||||
|
|
||||||
;; VARS
|
;; VARS
|
||||||
disable-paste (mf/use-var false)
|
disable-paste (mf/use-var false)
|
||||||
@ -163,34 +168,43 @@
|
|||||||
selected-frames (into #{} (map :frame-id) selected-shapes)
|
selected-frames (into #{} (map :frame-id) selected-shapes)
|
||||||
|
|
||||||
;; Only when we have all the selected shapes in one frame
|
;; Only when we have all the selected shapes in one frame
|
||||||
selected-frame (when (= (count selected-frames) 1) (get base-objects (first selected-frames)))
|
selected-frame (when (= (count selected-frames) 1)
|
||||||
|
(get base-objects (first selected-frames)))
|
||||||
|
|
||||||
editing-shape (when edition (get base-objects edition))
|
edit-path-state (get edit-path edition)
|
||||||
|
edit-path-mode (get edit-path-state :edit-mode)
|
||||||
|
|
||||||
edit-path (get edit-path edition)
|
path-editing? (some? edit-path-state)
|
||||||
edit-path-mode (get edit-path :edit-mode)
|
path-drawing? (or (= edit-path-mode :draw)
|
||||||
|
(and (= :path (get drawing-obj :type))
|
||||||
|
(not= :curve drawing-tool)))
|
||||||
|
|
||||||
|
editing-shape (when edition
|
||||||
|
(get base-objects edition))
|
||||||
|
|
||||||
|
editing-shape (mf/with-memo [editing-shape path-editing? base-objects]
|
||||||
|
(if path-editing?
|
||||||
|
(path/convert-to-path editing-shape base-objects)
|
||||||
|
editing-shape))
|
||||||
|
|
||||||
create-comment? (= :comments drawing-tool)
|
create-comment? (= :comments drawing-tool)
|
||||||
drawing-path? (or (= edit-path-mode :draw)
|
|
||||||
(= :path (get drawing-obj :type)))
|
|
||||||
|
|
||||||
node-editing? (cfh/path-shape? editing-shape)
|
|
||||||
text-editing? (cfh/text-shape? editing-shape)
|
text-editing? (cfh/text-shape? editing-shape)
|
||||||
grid-editing? (and edition (ctl/grid-layout? base-objects edition))
|
grid-editing? (and edition (ctl/grid-layout? base-objects edition))
|
||||||
|
|
||||||
mode-inspect? (= options-mode :inspect)
|
mode-inspect? (= options-mode :inspect)
|
||||||
|
|
||||||
on-click (actions/on-click hover selected edition drawing-path? drawing-tool space? selrect z?)
|
on-click (actions/on-click hover selected edition path-drawing? drawing-tool space? selrect z?)
|
||||||
on-context-menu (actions/on-context-menu hover hover-ids read-only?)
|
on-context-menu (actions/on-context-menu hover hover-ids read-only?)
|
||||||
on-double-click (actions/on-double-click hover hover-ids hover-top-frame-id drawing-path? base-objects edition drawing-tool z? read-only?)
|
on-double-click (actions/on-double-click hover hover-ids hover-top-frame-id path-drawing? base-objects edition drawing-tool z? read-only?)
|
||||||
|
|
||||||
comp-inst-ref (mf/use-ref false)
|
comp-inst-ref (mf/use-ref false)
|
||||||
on-drag-enter (actions/on-drag-enter comp-inst-ref)
|
on-drag-enter (actions/on-drag-enter comp-inst-ref)
|
||||||
on-drag-over (actions/on-drag-over move-stream)
|
on-drag-over (actions/on-drag-over move-stream)
|
||||||
on-drag-end (actions/on-drag-over comp-inst-ref)
|
on-drag-end (actions/on-drag-over comp-inst-ref)
|
||||||
on-drop (actions/on-drop file comp-inst-ref)
|
on-drop (actions/on-drop file comp-inst-ref)
|
||||||
on-pointer-down (actions/on-pointer-down @hover selected edition drawing-tool text-editing? node-editing? grid-editing?
|
on-pointer-down (actions/on-pointer-down @hover selected edition drawing-tool text-editing? path-editing? grid-editing?
|
||||||
drawing-path? create-comment? space? panning z? read-only?)
|
path-drawing? create-comment? space? panning z? read-only?)
|
||||||
|
|
||||||
on-pointer-up (actions/on-pointer-up disable-paste)
|
on-pointer-up (actions/on-pointer-up disable-paste)
|
||||||
|
|
||||||
@ -236,14 +250,14 @@
|
|||||||
(or drawing-obj transform))
|
(or drawing-obj transform))
|
||||||
show-selrect? (and selrect (empty? drawing) (not text-editing?))
|
show-selrect? (and selrect (empty? drawing) (not text-editing?))
|
||||||
show-measures? (and (not transform)
|
show-measures? (and (not transform)
|
||||||
(not node-editing?)
|
(not path-editing?)
|
||||||
(or show-distances? mode-inspect? read-only?))
|
(or show-distances? mode-inspect? read-only?))
|
||||||
show-artboard-names? (contains? layout :display-artboard-names)
|
show-artboard-names? (contains? layout :display-artboard-names)
|
||||||
hide-ui? (contains? layout :hide-ui)
|
hide-ui? (contains? layout :hide-ui)
|
||||||
show-rulers? (and (contains? layout :rulers) (not hide-ui?))
|
show-rulers? (and (contains? layout :rulers) (not hide-ui?))
|
||||||
|
|
||||||
|
|
||||||
disabled-guides? (or drawing-tool transform drawing-path? node-editing?)
|
disabled-guides? (or drawing-tool transform path-drawing? path-editing?)
|
||||||
|
|
||||||
single-select? (= (count selected-shapes) 1)
|
single-select? (= (count selected-shapes) 1)
|
||||||
|
|
||||||
@ -276,24 +290,34 @@
|
|||||||
|
|
||||||
rule-area-size (/ rulers/ruler-area-size zoom)]
|
rule-area-size (/ rulers/ruler-area-size zoom)]
|
||||||
|
|
||||||
(hooks/setup-dom-events zoom disable-paste in-viewport? read-only? drawing-tool drawing-path?)
|
(hooks/setup-dom-events zoom disable-paste in-viewport? read-only? drawing-tool path-drawing?)
|
||||||
(hooks/setup-viewport-size vport viewport-ref)
|
(hooks/setup-viewport-size vport viewport-ref)
|
||||||
(hooks/setup-cursor cursor alt? mod? space? panning drawing-tool drawing-path? node-editing? z? read-only?)
|
(hooks/setup-cursor cursor alt? mod? space? panning drawing-tool path-drawing? path-editing? z? read-only?)
|
||||||
(hooks/setup-keyboard alt? mod? space? z? shift?)
|
(hooks/setup-keyboard alt? mod? space? z? shift?)
|
||||||
(hooks/setup-hover-shapes page-id move-stream base-objects transform selected mod? hover measure-hover
|
(hooks/setup-hover-shapes page-id move-stream base-objects transform selected mod? hover measure-hover
|
||||||
hover-ids hover-top-frame-id @hover-disabled? focus zoom show-measures?)
|
hover-ids hover-top-frame-id @hover-disabled? focus zoom show-measures?)
|
||||||
(hooks/setup-viewport-modifiers modifiers base-objects)
|
(hooks/setup-viewport-modifiers modifiers base-objects)
|
||||||
(hooks/setup-shortcuts node-editing? drawing-path? text-editing? grid-editing?)
|
(hooks/setup-shortcuts path-editing? path-drawing? text-editing? grid-editing?)
|
||||||
(hooks/setup-active-frames base-objects hover-ids selected active-frames zoom transform vbox)
|
(hooks/setup-active-frames base-objects hover-ids selected active-frames zoom transform vbox)
|
||||||
|
|
||||||
[:div {:class (stl/css :viewport) :style #js {"--zoom" zoom} :data-testid "viewport"}
|
[:div {:class (stl/css :viewport) :style #js {"--zoom" zoom} :data-testid "viewport"}
|
||||||
(when (:can-edit permissions)
|
(when (:can-edit permissions)
|
||||||
[:> top-bar/top-bar* {:layout layout
|
(if read-only?
|
||||||
:selected selected-shapes
|
[:> view-only-bar* {}]
|
||||||
:edit-path edit-path
|
[:*
|
||||||
:drawing drawing
|
(when-not hide-ui?
|
||||||
:edition edition
|
[:> top-toolbar* {:layout layout}])
|
||||||
:is-read-only read-only?}])
|
|
||||||
|
(when (and ^boolean path-editing?
|
||||||
|
^boolean single-select?)
|
||||||
|
[:> path-edition-bar* {:shape editing-shape
|
||||||
|
:edit-path-state edit-path-state
|
||||||
|
:layout layout}])
|
||||||
|
|
||||||
|
(when (and ^boolean grid-editing?
|
||||||
|
^boolean single-select?)
|
||||||
|
[:> grid-edition-bar* {:shape editing-shape}])]))
|
||||||
|
|
||||||
[:div {:class (stl/css :viewport-overlays)}
|
[:div {:class (stl/css :viewport-overlays)}
|
||||||
;; The behaviour inside a foreign object is a bit different that in plain HTML so we wrap
|
;; The behaviour inside a foreign object is a bit different that in plain HTML so we wrap
|
||||||
;; inside a foreign object "dummy" so this awkward behaviour is take into account
|
;; inside a foreign object "dummy" so this awkward behaviour is take into account
|
||||||
@ -512,7 +536,8 @@
|
|||||||
:on-frame-leave on-frame-leave
|
:on-frame-leave on-frame-leave
|
||||||
:on-frame-select on-frame-select}])
|
:on-frame-select on-frame-select}])
|
||||||
|
|
||||||
(when show-draw-area?
|
(when (and ^boolean show-draw-area?
|
||||||
|
^boolean (cts/shape? drawing-obj))
|
||||||
[:> drawarea/draw-area*
|
[:> drawarea/draw-area*
|
||||||
{:shape drawing-obj
|
{:shape drawing-obj
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
@ -616,8 +641,9 @@
|
|||||||
(when show-selection-handlers?
|
(when show-selection-handlers?
|
||||||
[:g.selection-handlers {:clipPath "url(#clip-handlers)"}
|
[:g.selection-handlers {:clipPath "url(#clip-handlers)"}
|
||||||
(when-not text-editing?
|
(when-not text-editing?
|
||||||
(if editing-shape
|
(if (and editing-shape path-editing?)
|
||||||
[:> path-editor* {:shape editing-shape
|
[:> path-editor* {:shape editing-shape
|
||||||
|
:state edit-path-state
|
||||||
:zoom zoom}]
|
:zoom zoom}]
|
||||||
(when selected-shapes
|
(when selected-shapes
|
||||||
[:> selection/handlers*
|
[:> selection/handlers*
|
||||||
|
|||||||
@ -7,13 +7,19 @@
|
|||||||
(ns app.main.ui.workspace.viewport.drawarea
|
(ns app.main.ui.workspace.viewport.drawarea
|
||||||
"Drawing components."
|
"Drawing components."
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
[app.common.types.shape :as cts]
|
[app.main.refs :as refs]
|
||||||
[app.main.ui.shapes.path :refer [path-shape]]
|
[app.main.ui.shapes.path :refer [path-shape]]
|
||||||
[app.main.ui.workspace.shapes :as shapes]
|
[app.main.ui.workspace.shapes :as shapes]
|
||||||
[app.main.ui.workspace.shapes.path.editor :refer [path-editor*]]
|
[app.main.ui.workspace.shapes.path.editor :refer [path-editor*]]
|
||||||
|
[okulary.core :as l]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
|
(defn- make-edit-path-ref [id]
|
||||||
|
(let [get-fn #(dm/get-in % [:edit-path id])]
|
||||||
|
(l/derived get-fn refs/workspace-local)))
|
||||||
|
|
||||||
(mf/defc generic-draw-area*
|
(mf/defc generic-draw-area*
|
||||||
{::mf/private true}
|
{::mf/private true}
|
||||||
[{:keys [shape zoom]}]
|
[{:keys [shape zoom]}]
|
||||||
@ -29,17 +35,32 @@
|
|||||||
:fill "none"
|
:fill "none"
|
||||||
:stroke-width (/ 1 zoom)}}])))
|
:stroke-width (/ 1 zoom)}}])))
|
||||||
|
|
||||||
|
(mf/defc path-draw-area*
|
||||||
|
{::mf/private true}
|
||||||
|
[{:keys [shape] :as props}]
|
||||||
|
(let [shape-id
|
||||||
|
(dm/get-prop shape :id)
|
||||||
|
|
||||||
|
edit-path-ref
|
||||||
|
(mf/with-memo [shape-id]
|
||||||
|
(make-edit-path-ref shape-id))
|
||||||
|
|
||||||
|
edit-path-state
|
||||||
|
(mf/deref edit-path-ref)
|
||||||
|
|
||||||
|
props
|
||||||
|
(mf/spread-props props {:state edit-path-state})]
|
||||||
|
|
||||||
|
[:> path-editor* props]))
|
||||||
|
|
||||||
(mf/defc draw-area*
|
(mf/defc draw-area*
|
||||||
[{:keys [shape zoom tool] :as props}]
|
[{:keys [shape zoom tool] :as props}]
|
||||||
|
[:g.draw-area
|
||||||
|
[:g {:style {:pointer-events "none"}}
|
||||||
|
[:& shapes/shape-wrapper {:shape shape}]]
|
||||||
|
|
||||||
;; Prevent rendering something that it's not a shape.
|
(case tool
|
||||||
(when (cts/shape? shape)
|
:path [:> path-draw-area* props]
|
||||||
[:g.draw-area
|
:curve [:& path-shape {:shape shape :zoom zoom}]
|
||||||
[:g {:style {:pointer-events "none"}}
|
#_:default [:> generic-draw-area* props])])
|
||||||
[:& shapes/shape-wrapper {:shape shape}]]
|
|
||||||
|
|
||||||
(case tool
|
|
||||||
:path [:> path-editor* props]
|
|
||||||
:curve [:& path-shape {:shape shape :zoom zoom}]
|
|
||||||
#_:default [:> generic-draw-area* props])]))
|
|
||||||
|
|
||||||
|
|||||||
@ -67,8 +67,8 @@
|
|||||||
:separate-nodes segments-selected?})))
|
:separate-nodes segments-selected?})))
|
||||||
|
|
||||||
(mf/defc path-actions*
|
(mf/defc path-actions*
|
||||||
[{:keys [shape edit-path]}]
|
[{:keys [shape state]}]
|
||||||
(let [{:keys [edit-mode selected-points snap-toggled]} edit-path
|
(let [{:keys [edit-mode selected-points snap-toggled]} state
|
||||||
|
|
||||||
content (:content shape)
|
content (:content shape)
|
||||||
|
|
||||||
|
|||||||
@ -7,19 +7,20 @@
|
|||||||
(ns app.main.ui.workspace.viewport.top-bar
|
(ns app.main.ui.workspace.viewport.top-bar
|
||||||
(:require-macros [app.main.style :as stl])
|
(:require-macros [app.main.style :as stl])
|
||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
|
||||||
[app.common.files.helpers :as cfh]
|
|
||||||
[app.common.types.shape.layout :as ctl]
|
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.data.workspace.common :as dwc]
|
[app.main.data.workspace.common :as dwc]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.workspace.top-toolbar :refer [top-toolbar]]
|
|
||||||
[app.main.ui.workspace.viewport.grid-layout-editor :refer [grid-edition-actions]]
|
[app.main.ui.workspace.viewport.grid-layout-editor :refer [grid-edition-actions]]
|
||||||
[app.main.ui.workspace.viewport.path-actions :refer [path-actions*]]
|
[app.main.ui.workspace.viewport.path-actions :refer [path-actions*]]
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(mf/defc view-only-actions*
|
;; FIXME: this namespace should be renamed and all translation files
|
||||||
|
;; should also be renamed. But this should be done on development
|
||||||
|
;; branch.
|
||||||
|
|
||||||
|
(mf/defc view-only-bar*
|
||||||
|
{::mf/private true}
|
||||||
[]
|
[]
|
||||||
(let [handle-close-view-mode
|
(let [handle-close-view-mode
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
@ -37,44 +38,15 @@
|
|||||||
:on-click handle-close-view-mode}
|
:on-click handle-close-view-mode}
|
||||||
(tr "workspace.top-bar.read-only.done")]]]))
|
(tr "workspace.top-bar.read-only.done")]]]))
|
||||||
|
|
||||||
(mf/defc top-bar*
|
(mf/defc path-edition-bar*
|
||||||
[{:keys [layout drawing is-read-only edition selected edit-path]}]
|
[{:keys [layout edit-path-state shape]}]
|
||||||
(let [rulers? (contains? layout :rulers)
|
(let [rulers? (contains? layout :rulers)
|
||||||
hide-ui? (contains? layout :hide-ui)
|
class (stl/css-case
|
||||||
|
:viewport-actions-path true
|
||||||
|
:viewport-actions-no-rulers (not rulers?))]
|
||||||
|
[:div {:class class}
|
||||||
|
[:> path-actions* {:shape shape :state edit-path-state}]]))
|
||||||
|
|
||||||
drawing-obj (get drawing :object)
|
(mf/defc grid-edition-bar*
|
||||||
shape (or drawing-obj (-> selected first))
|
[{:keys [shape]}]
|
||||||
shape-id (dm/get-prop shape :id)
|
[:& grid-edition-actions {:shape shape}])
|
||||||
|
|
||||||
single? (= (count selected) 1)
|
|
||||||
editing? (= shape-id edition)
|
|
||||||
|
|
||||||
draw-path? (and (some? drawing-obj)
|
|
||||||
(cfh/path-shape? drawing-obj)
|
|
||||||
(not= :curve (:tool drawing)))
|
|
||||||
|
|
||||||
is-path-edition
|
|
||||||
(or (and single? editing?
|
|
||||||
(and (not (cfh/text-shape? shape))
|
|
||||||
(not (cfh/frame-shape? shape))))
|
|
||||||
draw-path?)
|
|
||||||
|
|
||||||
grid-edition?
|
|
||||||
(and single? editing? (ctl/grid-layout? shape))]
|
|
||||||
|
|
||||||
[:*
|
|
||||||
(when-not ^boolean hide-ui?
|
|
||||||
[:& top-toolbar {:layout layout}])
|
|
||||||
|
|
||||||
(cond
|
|
||||||
^boolean
|
|
||||||
is-read-only
|
|
||||||
[:> view-only-actions*]
|
|
||||||
|
|
||||||
^boolean
|
|
||||||
is-path-edition
|
|
||||||
[:div {:class (stl/css-case :viewport-actions-path true :viewport-actions-no-rulers (not rulers?))}
|
|
||||||
[:> path-actions* {:shape shape :edit-path edit-path}]]
|
|
||||||
|
|
||||||
grid-edition?
|
|
||||||
[:& grid-edition-actions {:shape shape}])]))
|
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.files.helpers :as cfh]
|
[app.common.files.helpers :as cfh]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
|
[app.common.types.path :as path]
|
||||||
[app.common.types.shape :as cts]
|
[app.common.types.shape :as cts]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.main.data.workspace.transforms :as dwt]
|
[app.main.data.workspace.transforms :as dwt]
|
||||||
@ -26,6 +27,7 @@
|
|||||||
[app.main.ui.workspace.shapes.text.editor :as editor-v1]
|
[app.main.ui.workspace.shapes.text.editor :as editor-v1]
|
||||||
[app.main.ui.workspace.shapes.text.text-edition-outline :refer [text-edition-outline]]
|
[app.main.ui.workspace.shapes.text.text-edition-outline :refer [text-edition-outline]]
|
||||||
[app.main.ui.workspace.shapes.text.v2-editor :as editor-v2]
|
[app.main.ui.workspace.shapes.text.v2-editor :as editor-v2]
|
||||||
|
[app.main.ui.workspace.top-toolbar :refer [top-toolbar*]]
|
||||||
[app.main.ui.workspace.viewport.actions :as actions]
|
[app.main.ui.workspace.viewport.actions :as actions]
|
||||||
[app.main.ui.workspace.viewport.comments :as comments]
|
[app.main.ui.workspace.viewport.comments :as comments]
|
||||||
[app.main.ui.workspace.viewport.debug :as wvd]
|
[app.main.ui.workspace.viewport.debug :as wvd]
|
||||||
@ -44,7 +46,7 @@
|
|||||||
[app.main.ui.workspace.viewport.selection :as selection]
|
[app.main.ui.workspace.viewport.selection :as selection]
|
||||||
[app.main.ui.workspace.viewport.snap-distances :as snap-distances]
|
[app.main.ui.workspace.viewport.snap-distances :as snap-distances]
|
||||||
[app.main.ui.workspace.viewport.snap-points :as snap-points]
|
[app.main.ui.workspace.viewport.snap-points :as snap-points]
|
||||||
[app.main.ui.workspace.viewport.top-bar :as top-bar]
|
[app.main.ui.workspace.viewport.top-bar :refer [path-edition-bar* grid-edition-bar* view-only-bar*]]
|
||||||
[app.main.ui.workspace.viewport.utils :as utils]
|
[app.main.ui.workspace.viewport.utils :as utils]
|
||||||
[app.main.ui.workspace.viewport.viewport-ref :refer [create-viewport-ref]]
|
[app.main.ui.workspace.viewport.viewport-ref :refer [create-viewport-ref]]
|
||||||
[app.main.ui.workspace.viewport.widgets :as widgets]
|
[app.main.ui.workspace.viewport.widgets :as widgets]
|
||||||
@ -161,38 +163,45 @@
|
|||||||
drawing-tool (:tool drawing)
|
drawing-tool (:tool drawing)
|
||||||
drawing-obj (:object drawing)
|
drawing-obj (:object drawing)
|
||||||
|
|
||||||
|
|
||||||
selected-frames (into #{} (map :frame-id) selected-shapes)
|
selected-frames (into #{} (map :frame-id) selected-shapes)
|
||||||
|
|
||||||
;; Only when we have all the selected shapes in one frame
|
;; Only when we have all the selected shapes in one frame
|
||||||
selected-frame (when (= (count selected-frames) 1) (get base-objects (first selected-frames)))
|
selected-frame (when (= (count selected-frames) 1) (get base-objects (first selected-frames)))
|
||||||
|
|
||||||
editing-shape (when edition (get base-objects edition))
|
edit-path-state (get edit-path edition)
|
||||||
|
edit-path-mode (get edit-path-state :edit-mode)
|
||||||
|
|
||||||
edit-path (get edit-path edition)
|
path-editing? (some? edit-path-state)
|
||||||
edit-path-mode (get edit-path :edit-mode)
|
path-drawing? (or (= edit-path-mode :draw)
|
||||||
|
(and (= :path (get drawing-obj :type))
|
||||||
|
(not= :curve drawing-tool)))
|
||||||
|
|
||||||
|
editing-shape (when edition
|
||||||
|
(get base-objects edition))
|
||||||
|
|
||||||
|
editing-shape (mf/with-memo [editing-shape path-editing? base-objects]
|
||||||
|
(if path-editing?
|
||||||
|
(path/convert-to-path editing-shape base-objects)
|
||||||
|
editing-shape))
|
||||||
|
|
||||||
create-comment? (= :comments drawing-tool)
|
create-comment? (= :comments drawing-tool)
|
||||||
drawing-path? (or (= edit-path-mode :draw)
|
|
||||||
(= :path (get drawing-obj :type)))
|
|
||||||
|
|
||||||
node-editing? (cfh/path-shape? editing-shape)
|
|
||||||
text-editing? (cfh/text-shape? editing-shape)
|
text-editing? (cfh/text-shape? editing-shape)
|
||||||
grid-editing? (and edition (ctl/grid-layout? base-objects edition))
|
grid-editing? (and edition (ctl/grid-layout? base-objects edition))
|
||||||
|
|
||||||
mode-inspect? (= options-mode :inspect)
|
mode-inspect? (= options-mode :inspect)
|
||||||
|
|
||||||
on-click (actions/on-click hover selected edition drawing-path? drawing-tool space? selrect z?)
|
on-click (actions/on-click hover selected edition path-drawing? drawing-tool space? selrect z?)
|
||||||
on-context-menu (actions/on-context-menu hover hover-ids read-only?)
|
on-context-menu (actions/on-context-menu hover hover-ids read-only?)
|
||||||
on-double-click (actions/on-double-click hover hover-ids hover-top-frame-id drawing-path? base-objects edition drawing-tool z? read-only?)
|
on-double-click (actions/on-double-click hover hover-ids hover-top-frame-id path-drawing? base-objects edition drawing-tool z? read-only?)
|
||||||
|
|
||||||
comp-inst-ref (mf/use-ref false)
|
comp-inst-ref (mf/use-ref false)
|
||||||
on-drag-enter (actions/on-drag-enter comp-inst-ref)
|
on-drag-enter (actions/on-drag-enter comp-inst-ref)
|
||||||
on-drag-over (actions/on-drag-over move-stream)
|
on-drag-over (actions/on-drag-over move-stream)
|
||||||
on-drag-end (actions/on-drag-over comp-inst-ref)
|
on-drag-end (actions/on-drag-over comp-inst-ref)
|
||||||
on-drop (actions/on-drop file comp-inst-ref)
|
on-drop (actions/on-drop file comp-inst-ref)
|
||||||
on-pointer-down (actions/on-pointer-down @hover selected edition drawing-tool text-editing? node-editing? grid-editing?
|
on-pointer-down (actions/on-pointer-down @hover selected edition drawing-tool text-editing? path-editing? grid-editing?
|
||||||
drawing-path? create-comment? space? panning z? read-only?)
|
path-drawing? create-comment? space? panning z? read-only?)
|
||||||
|
|
||||||
on-pointer-up (actions/on-pointer-up disable-paste)
|
on-pointer-up (actions/on-pointer-up disable-paste)
|
||||||
|
|
||||||
@ -238,14 +247,14 @@
|
|||||||
(or drawing-obj transform))
|
(or drawing-obj transform))
|
||||||
show-selrect? (and selrect (empty? drawing) (not text-editing?))
|
show-selrect? (and selrect (empty? drawing) (not text-editing?))
|
||||||
show-measures? (and (not transform)
|
show-measures? (and (not transform)
|
||||||
(not node-editing?)
|
(not path-editing?)
|
||||||
(or show-distances? mode-inspect?))
|
(or show-distances? mode-inspect?))
|
||||||
show-artboard-names? (contains? layout :display-artboard-names)
|
show-artboard-names? (contains? layout :display-artboard-names)
|
||||||
hide-ui? (contains? layout :hide-ui)
|
hide-ui? (contains? layout :hide-ui)
|
||||||
show-rulers? (and (contains? layout :rulers) (not hide-ui?))
|
show-rulers? (and (contains? layout :rulers) (not hide-ui?))
|
||||||
|
|
||||||
|
|
||||||
disabled-guides? (or drawing-tool transform drawing-path? node-editing?)
|
disabled-guides? (or drawing-tool transform path-drawing? path-editing?)
|
||||||
|
|
||||||
single-select? (= (count selected-shapes) 1)
|
single-select? (= (count selected-shapes) 1)
|
||||||
|
|
||||||
@ -340,23 +349,33 @@
|
|||||||
(wasm.api/show-grid @hover-top-frame-id)
|
(wasm.api/show-grid @hover-top-frame-id)
|
||||||
(wasm.api/clear-grid))))
|
(wasm.api/clear-grid))))
|
||||||
|
|
||||||
(hooks/setup-dom-events zoom disable-paste in-viewport? read-only? drawing-tool drawing-path?)
|
(hooks/setup-dom-events zoom disable-paste in-viewport? read-only? drawing-tool path-drawing?)
|
||||||
(hooks/setup-viewport-size vport viewport-ref)
|
(hooks/setup-viewport-size vport viewport-ref)
|
||||||
(hooks/setup-cursor cursor alt? mod? space? panning drawing-tool drawing-path? node-editing? z? read-only?)
|
(hooks/setup-cursor cursor alt? mod? space? panning drawing-tool path-drawing? path-editing? z? read-only?)
|
||||||
(hooks/setup-keyboard alt? mod? space? z? shift?)
|
(hooks/setup-keyboard alt? mod? space? z? shift?)
|
||||||
(hooks/setup-hover-shapes page-id move-stream base-objects transform selected mod? hover measure-hover
|
(hooks/setup-hover-shapes page-id move-stream base-objects transform selected mod? hover measure-hover
|
||||||
hover-ids hover-top-frame-id @hover-disabled? focus zoom show-measures?)
|
hover-ids hover-top-frame-id @hover-disabled? focus zoom show-measures?)
|
||||||
(hooks/setup-shortcuts node-editing? drawing-path? text-editing? grid-editing?)
|
(hooks/setup-shortcuts path-editing? path-drawing? text-editing? grid-editing?)
|
||||||
(hooks/setup-active-frames base-objects hover-ids selected active-frames zoom transform vbox)
|
(hooks/setup-active-frames base-objects hover-ids selected active-frames zoom transform vbox)
|
||||||
|
|
||||||
[:div {:class (stl/css :viewport) :style #js {"--zoom" zoom} :data-testid "viewport"}
|
[:div {:class (stl/css :viewport) :style #js {"--zoom" zoom} :data-testid "viewport"}
|
||||||
(when (:can-edit permissions)
|
(when (:can-edit permissions)
|
||||||
[:> top-bar/top-bar* {:layout layout
|
(if read-only?
|
||||||
:selected selected-shapes
|
[:> view-only-bar* {}]
|
||||||
:edit-path edit-path
|
[:*
|
||||||
:drawing drawing
|
(when-not hide-ui?
|
||||||
:edition edition
|
[:> top-toolbar* {:layout layout}])
|
||||||
:is-read-only read-only?}])
|
|
||||||
|
(when (and ^boolean path-editing?
|
||||||
|
^boolean single-select?)
|
||||||
|
[:> path-edition-bar* {:shape editing-shape
|
||||||
|
:edit-path-state edit-path-state
|
||||||
|
:layout layout}])
|
||||||
|
|
||||||
|
(when (and ^boolean grid-editing?
|
||||||
|
^boolean single-select?)
|
||||||
|
[:> grid-edition-bar* {:shape editing-shape}])]))
|
||||||
|
|
||||||
[:div {:class (stl/css :viewport-overlays)}
|
[:div {:class (stl/css :viewport-overlays)}
|
||||||
(when show-comments?
|
(when show-comments?
|
||||||
[:> comments/comments-layer* {:vbox vbox
|
[:> comments/comments-layer* {:vbox vbox
|
||||||
@ -521,7 +540,8 @@
|
|||||||
:on-frame-leave on-frame-leave
|
:on-frame-leave on-frame-leave
|
||||||
:on-frame-select on-frame-select}])
|
:on-frame-select on-frame-select}])
|
||||||
|
|
||||||
(when show-draw-area?
|
(when (and ^boolean show-draw-area?
|
||||||
|
^boolean (cts/shape? drawing-obj))
|
||||||
[:> drawarea/draw-area*
|
[:> drawarea/draw-area*
|
||||||
{:shape drawing-obj
|
{:shape drawing-obj
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
@ -625,8 +645,9 @@
|
|||||||
(when show-selection-handlers?
|
(when show-selection-handlers?
|
||||||
[:g.selection-handlers {:clipPath "url(#clip-handlers)"}
|
[:g.selection-handlers {:clipPath "url(#clip-handlers)"}
|
||||||
(when-not text-editing?
|
(when-not text-editing?
|
||||||
(if editing-shape
|
(if (and editing-shape path-editing?)
|
||||||
[:> path-editor* {:shape editing-shape
|
[:> path-editor* {:shape editing-shape
|
||||||
|
:state edit-path-state
|
||||||
:zoom zoom}]
|
:zoom zoom}]
|
||||||
(when selected-shapes
|
(when selected-shapes
|
||||||
[:> selection/handlers*
|
[:> selection/handlers*
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user